You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

conn.go 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package proxyprotocol
  4. import (
  5. "bufio"
  6. "bytes"
  7. "encoding/binary"
  8. "io"
  9. "net"
  10. "strconv"
  11. "strings"
  12. "sync"
  13. "time"
  14. "code.gitea.io/gitea/modules/log"
  15. )
  16. var (
  17. // v1Prefix is the string we look for at the start of a connection
  18. // to check if this connection is using the proxy protocol
  19. v1Prefix = []byte("PROXY ")
  20. v1PrefixLen = len(v1Prefix)
  21. v2Prefix = []byte("\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A")
  22. v2PrefixLen = len(v2Prefix)
  23. )
  24. // Conn is used to wrap and underlying connection which is speaking the
  25. // Proxy Protocol. RemoteAddr() will return the address of the client
  26. // instead of the proxy address.
  27. type Conn struct {
  28. bufReader *bufio.Reader
  29. conn net.Conn
  30. localAddr net.Addr
  31. remoteAddr net.Addr
  32. once sync.Once
  33. proxyHeaderTimeout time.Duration
  34. acceptUnknown bool
  35. }
  36. // NewConn is used to wrap a net.Conn speaking the proxy protocol into
  37. // a proxyprotocol.Conn
  38. func NewConn(conn net.Conn, timeout time.Duration) *Conn {
  39. pConn := &Conn{
  40. bufReader: bufio.NewReader(conn),
  41. conn: conn,
  42. proxyHeaderTimeout: timeout,
  43. }
  44. return pConn
  45. }
  46. // Read reads data from the connection.
  47. // It will initially read the proxy protocol header.
  48. // If there is an error parsing the header, it is returned and the socket is closed.
  49. func (p *Conn) Read(b []byte) (int, error) {
  50. if err := p.readProxyHeaderOnce(); err != nil {
  51. return 0, err
  52. }
  53. return p.bufReader.Read(b)
  54. }
  55. // ReadFrom reads data from a provided reader and copies it to the connection.
  56. func (p *Conn) ReadFrom(r io.Reader) (int64, error) {
  57. if err := p.readProxyHeaderOnce(); err != nil {
  58. return 0, err
  59. }
  60. if rf, ok := p.conn.(io.ReaderFrom); ok {
  61. return rf.ReadFrom(r)
  62. }
  63. return io.Copy(p.conn, r)
  64. }
  65. // WriteTo reads data from the connection and writes it to the writer.
  66. // It will initially read the proxy protocol header.
  67. // If there is an error parsing the header, it is returned and the socket is closed.
  68. func (p *Conn) WriteTo(w io.Writer) (int64, error) {
  69. if err := p.readProxyHeaderOnce(); err != nil {
  70. return 0, err
  71. }
  72. return p.bufReader.WriteTo(w)
  73. }
  74. // Write writes data to the connection.
  75. // Write can be made to time out and return an error after a fixed
  76. // time limit; see SetDeadline and SetWriteDeadline.
  77. func (p *Conn) Write(b []byte) (int, error) {
  78. if err := p.readProxyHeaderOnce(); err != nil {
  79. return 0, err
  80. }
  81. return p.conn.Write(b)
  82. }
  83. // Close closes the connection.
  84. // Any blocked Read or Write operations will be unblocked and return errors.
  85. func (p *Conn) Close() error {
  86. return p.conn.Close()
  87. }
  88. // LocalAddr returns the local network address.
  89. func (p *Conn) LocalAddr() net.Addr {
  90. _ = p.readProxyHeaderOnce()
  91. if p.localAddr != nil {
  92. return p.localAddr
  93. }
  94. return p.conn.LocalAddr()
  95. }
  96. // RemoteAddr returns the address of the client if the proxy
  97. // protocol is being used, otherwise just returns the address of
  98. // the socket peer. If there is an error parsing the header, the
  99. // address of the client is not returned, and the socket is closed.
  100. // One implication of this is that the call could block if the
  101. // client is slow. Using a Deadline is recommended if this is called
  102. // before Read()
  103. func (p *Conn) RemoteAddr() net.Addr {
  104. _ = p.readProxyHeaderOnce()
  105. if p.remoteAddr != nil {
  106. return p.remoteAddr
  107. }
  108. return p.conn.RemoteAddr()
  109. }
  110. // SetDeadline sets the read and write deadlines associated
  111. // with the connection. It is equivalent to calling both
  112. // SetReadDeadline and SetWriteDeadline.
  113. //
  114. // A deadline is an absolute time after which I/O operations
  115. // fail instead of blocking. The deadline applies to all future
  116. // and pending I/O, not just the immediately following call to
  117. // Read or Write. After a deadline has been exceeded, the
  118. // connection can be refreshed by setting a deadline in the future.
  119. //
  120. // If the deadline is exceeded a call to Read or Write or to other
  121. // I/O methods will return an error that wraps os.ErrDeadlineExceeded.
  122. // This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
  123. // The error's Timeout method will return true, but note that there
  124. // are other possible errors for which the Timeout method will
  125. // return true even if the deadline has not been exceeded.
  126. //
  127. // An idle timeout can be implemented by repeatedly extending
  128. // the deadline after successful Read or Write calls.
  129. //
  130. // A zero value for t means I/O operations will not time out.
  131. func (p *Conn) SetDeadline(t time.Time) error {
  132. return p.conn.SetDeadline(t)
  133. }
  134. // SetReadDeadline sets the deadline for future Read calls
  135. // and any currently-blocked Read call.
  136. // A zero value for t means Read will not time out.
  137. func (p *Conn) SetReadDeadline(t time.Time) error {
  138. return p.conn.SetReadDeadline(t)
  139. }
  140. // SetWriteDeadline sets the deadline for future Write calls
  141. // and any currently-blocked Write call.
  142. // Even if write times out, it may return n > 0, indicating that
  143. // some of the data was successfully written.
  144. // A zero value for t means Write will not time out.
  145. func (p *Conn) SetWriteDeadline(t time.Time) error {
  146. return p.conn.SetWriteDeadline(t)
  147. }
  148. // readProxyHeaderOnce will ensure that the proxy header has been read
  149. func (p *Conn) readProxyHeaderOnce() (err error) {
  150. p.once.Do(func() {
  151. if err = p.readProxyHeader(); err != nil && err != io.EOF {
  152. log.Error("Failed to read proxy prefix: %v", err)
  153. p.Close()
  154. p.bufReader = bufio.NewReader(p.conn)
  155. }
  156. })
  157. return err
  158. }
  159. func (p *Conn) readProxyHeader() error {
  160. if p.proxyHeaderTimeout != 0 {
  161. readDeadLine := time.Now().Add(p.proxyHeaderTimeout)
  162. _ = p.conn.SetReadDeadline(readDeadLine)
  163. defer func() {
  164. _ = p.conn.SetReadDeadline(time.Time{})
  165. }()
  166. }
  167. inp, err := p.bufReader.Peek(v1PrefixLen)
  168. if err != nil {
  169. return err
  170. }
  171. if bytes.Equal(inp, v1Prefix) {
  172. return p.readV1ProxyHeader()
  173. }
  174. inp, err = p.bufReader.Peek(v2PrefixLen)
  175. if err != nil {
  176. return err
  177. }
  178. if bytes.Equal(inp, v2Prefix) {
  179. return p.readV2ProxyHeader()
  180. }
  181. return &ErrBadHeader{inp}
  182. }
  183. func (p *Conn) readV2ProxyHeader() error {
  184. // The binary header format starts with a constant 12 bytes block containing the
  185. // protocol signature :
  186. //
  187. // \x0D \x0A \x0D \x0A \x00 \x0D \x0A \x51 \x55 \x49 \x54 \x0A
  188. //
  189. // Note that this block contains a null byte at the 5th position, so it must not
  190. // be handled as a null-terminated string.
  191. if _, err := p.bufReader.Discard(v2PrefixLen); err != nil {
  192. // This shouldn't happen as we have already asserted that there should be enough in the buffer
  193. return err
  194. }
  195. // The next byte (the 13th one) is the protocol version and command.
  196. version, err := p.bufReader.ReadByte()
  197. if err != nil {
  198. return err
  199. }
  200. // The 14th byte contains the transport protocol and address family.otocol.
  201. familyByte, err := p.bufReader.ReadByte()
  202. if err != nil {
  203. return err
  204. }
  205. // The 15th and 16th bytes is the address length in bytes in network endian order.
  206. var addressLen uint16
  207. if err := binary.Read(p.bufReader, binary.BigEndian, &addressLen); err != nil {
  208. return err
  209. }
  210. // Now handle the version byte: (14th byte).
  211. // The highest four bits contains the version. As of this specification, it must
  212. // always be sent as \x2 and the receiver must only accept this value.
  213. if version>>4 != 0x2 {
  214. return &ErrBadHeader{append(v2Prefix, version, familyByte, uint8(addressLen>>8), uint8(addressLen&0xff))}
  215. }
  216. // The lowest four bits represents the command :
  217. switch version & 0xf {
  218. case 0x0:
  219. // - \x0 : LOCAL : the connection was established on purpose by the proxy
  220. // without being relayed. The connection endpoints are the sender and the
  221. // receiver. Such connections exist when the proxy sends health-checks to the
  222. // server. The receiver must accept this connection as valid and must use the
  223. // real connection endpoints and discard the protocol block including the
  224. // family which is ignored.
  225. // We therefore ignore the 14th, 15th and 16th bytes
  226. p.remoteAddr = p.conn.LocalAddr()
  227. p.localAddr = p.conn.RemoteAddr()
  228. return nil
  229. case 0x1:
  230. // - \x1 : PROXY : the connection was established on behalf of another node,
  231. // and reflects the original connection endpoints. The receiver must then use
  232. // the information provided in the protocol block to get original the address.
  233. default:
  234. // - other values are unassigned and must not be emitted by senders. Receivers
  235. // must drop connections presenting unexpected values here.
  236. return &ErrBadHeader{append(v2Prefix, version, familyByte, uint8(addressLen>>8), uint8(addressLen&0xff))}
  237. }
  238. // Now handle the familyByte byte: (15th byte).
  239. // The highest 4 bits contain the address family, the lowest 4 bits contain the protocol
  240. // The address family maps to the original socket family without necessarily
  241. // matching the values internally used by the system. It may be one of :
  242. //
  243. // - 0x0 : AF_UNSPEC : the connection is forwarded for an unknown, unspecified
  244. // or unsupported protocol. The sender should use this family when sending
  245. // LOCAL commands or when dealing with unsupported protocol families. The
  246. // receiver is free to accept the connection anyway and use the real endpoint
  247. // addresses or to reject it. The receiver should ignore address information.
  248. //
  249. // - 0x1 : AF_INET : the forwarded connection uses the AF_INET address family
  250. // (IPv4). The addresses are exactly 4 bytes each in network byte order,
  251. // followed by transport protocol information (typically ports).
  252. //
  253. // - 0x2 : AF_INET6 : the forwarded connection uses the AF_INET6 address family
  254. // (IPv6). The addresses are exactly 16 bytes each in network byte order,
  255. // followed by transport protocol information (typically ports).
  256. //
  257. // - 0x3 : AF_UNIX : the forwarded connection uses the AF_UNIX address family
  258. // (UNIX). The addresses are exactly 108 bytes each.
  259. //
  260. // - other values are unspecified and must not be emitted in version 2 of this
  261. // protocol and must be rejected as invalid by receivers.
  262. // The transport protocol is specified in the lowest 4 bits of the 14th byte :
  263. //
  264. // - 0x0 : UNSPEC : the connection is forwarded for an unknown, unspecified
  265. // or unsupported protocol. The sender should use this family when sending
  266. // LOCAL commands or when dealing with unsupported protocol families. The
  267. // receiver is free to accept the connection anyway and use the real endpoint
  268. // addresses or to reject it. The receiver should ignore address information.
  269. //
  270. // - 0x1 : STREAM : the forwarded connection uses a SOCK_STREAM protocol (eg:
  271. // TCP or UNIX_STREAM). When used with AF_INET/AF_INET6 (TCP), the addresses
  272. // are followed by the source and destination ports represented on 2 bytes
  273. // each in network byte order.
  274. //
  275. // - 0x2 : DGRAM : the forwarded connection uses a SOCK_DGRAM protocol (eg:
  276. // UDP or UNIX_DGRAM). When used with AF_INET/AF_INET6 (UDP), the addresses
  277. // are followed by the source and destination ports represented on 2 bytes
  278. // each in network byte order.
  279. //
  280. // - other values are unspecified and must not be emitted in version 2 of this
  281. // protocol and must be rejected as invalid by receivers.
  282. if familyByte>>4 == 0x0 || familyByte&0xf == 0x0 {
  283. // - hi 0x0 : AF_UNSPEC : the connection is forwarded for an unknown address type
  284. // or
  285. // - lo 0x0 : UNSPEC : the connection is forwarded for an unspecified protocol
  286. if !p.acceptUnknown {
  287. p.conn.Close()
  288. return &ErrBadHeader{append(v2Prefix, version, familyByte, uint8(addressLen>>8), uint8(addressLen&0xff))}
  289. }
  290. p.remoteAddr = p.conn.LocalAddr()
  291. p.localAddr = p.conn.RemoteAddr()
  292. _, err = p.bufReader.Discard(int(addressLen))
  293. return err
  294. }
  295. // other address or protocol
  296. if (familyByte>>4) > 0x3 || (familyByte&0xf) > 0x2 {
  297. return &ErrBadHeader{append(v2Prefix, version, familyByte, uint8(addressLen>>8), uint8(addressLen&0xff))}
  298. }
  299. // Handle AF_UNIX addresses
  300. if familyByte>>4 == 0x3 {
  301. // - \x31 : UNIX stream : the forwarded connection uses SOCK_STREAM over the
  302. // AF_UNIX protocol family. Address length is 2*108 = 216 bytes.
  303. // - \x32 : UNIX datagram : the forwarded connection uses SOCK_DGRAM over the
  304. // AF_UNIX protocol family. Address length is 2*108 = 216 bytes.
  305. if addressLen != 216 {
  306. return &ErrBadHeader{append(v2Prefix, version, familyByte, uint8(addressLen>>8), uint8(addressLen&0xff))}
  307. }
  308. remoteName := make([]byte, 108)
  309. localName := make([]byte, 108)
  310. if _, err := p.bufReader.Read(remoteName); err != nil {
  311. return err
  312. }
  313. if _, err := p.bufReader.Read(localName); err != nil {
  314. return err
  315. }
  316. protocol := "unix"
  317. if familyByte&0xf == 2 {
  318. protocol = "unixgram"
  319. }
  320. p.remoteAddr = &net.UnixAddr{
  321. Name: string(remoteName),
  322. Net: protocol,
  323. }
  324. p.localAddr = &net.UnixAddr{
  325. Name: string(localName),
  326. Net: protocol,
  327. }
  328. return nil
  329. }
  330. var remoteIP []byte
  331. var localIP []byte
  332. var remotePort uint16
  333. var localPort uint16
  334. if familyByte>>4 == 0x1 {
  335. // AF_INET
  336. // - \x11 : TCP over IPv4 : the forwarded connection uses TCP over the AF_INET
  337. // protocol family. Address length is 2*4 + 2*2 = 12 bytes.
  338. // - \x12 : UDP over IPv4 : the forwarded connection uses UDP over the AF_INET
  339. // protocol family. Address length is 2*4 + 2*2 = 12 bytes.
  340. if addressLen != 12 {
  341. return &ErrBadHeader{append(v2Prefix, version, familyByte, uint8(addressLen>>8), uint8(addressLen&0xff))}
  342. }
  343. remoteIP = make([]byte, 4)
  344. localIP = make([]byte, 4)
  345. } else {
  346. // AF_INET6
  347. // - \x21 : TCP over IPv6 : the forwarded connection uses TCP over the AF_INET6
  348. // protocol family. Address length is 2*16 + 2*2 = 36 bytes.
  349. // - \x22 : UDP over IPv6 : the forwarded connection uses UDP over the AF_INET6
  350. // protocol family. Address length is 2*16 + 2*2 = 36 bytes.
  351. if addressLen != 36 {
  352. return &ErrBadHeader{append(v2Prefix, version, familyByte, uint8(addressLen>>8), uint8(addressLen&0xff))}
  353. }
  354. remoteIP = make([]byte, 16)
  355. localIP = make([]byte, 16)
  356. }
  357. if _, err := p.bufReader.Read(remoteIP); err != nil {
  358. return err
  359. }
  360. if _, err := p.bufReader.Read(localIP); err != nil {
  361. return err
  362. }
  363. if err := binary.Read(p.bufReader, binary.BigEndian, &remotePort); err != nil {
  364. return err
  365. }
  366. if err := binary.Read(p.bufReader, binary.BigEndian, &localPort); err != nil {
  367. return err
  368. }
  369. if familyByte&0xf == 1 {
  370. p.remoteAddr = &net.TCPAddr{
  371. IP: remoteIP,
  372. Port: int(remotePort),
  373. }
  374. p.localAddr = &net.TCPAddr{
  375. IP: localIP,
  376. Port: int(localPort),
  377. }
  378. } else {
  379. p.remoteAddr = &net.UDPAddr{
  380. IP: remoteIP,
  381. Port: int(remotePort),
  382. }
  383. p.localAddr = &net.UDPAddr{
  384. IP: localIP,
  385. Port: int(localPort),
  386. }
  387. }
  388. return nil
  389. }
  390. func (p *Conn) readV1ProxyHeader() error {
  391. // Read until a newline
  392. header, err := p.bufReader.ReadString('\n')
  393. if err != nil {
  394. p.conn.Close()
  395. return err
  396. }
  397. if header[len(header)-2] != '\r' {
  398. return &ErrBadHeader{[]byte(header)}
  399. }
  400. // Strip the carriage return and new line
  401. header = header[:len(header)-2]
  402. // Split on spaces, should be (PROXY <type> <remote addr> <local addr> <remote port> <local port>)
  403. parts := strings.Split(header, " ")
  404. if len(parts) < 2 {
  405. p.conn.Close()
  406. return &ErrBadHeader{[]byte(header)}
  407. }
  408. // Verify the type is known
  409. switch parts[1] {
  410. case "UNKNOWN":
  411. if !p.acceptUnknown || len(parts) != 2 {
  412. p.conn.Close()
  413. return &ErrBadHeader{[]byte(header)}
  414. }
  415. p.remoteAddr = p.conn.LocalAddr()
  416. p.localAddr = p.conn.RemoteAddr()
  417. return nil
  418. case "TCP4":
  419. case "TCP6":
  420. default:
  421. p.conn.Close()
  422. return &ErrBadAddressType{parts[1]}
  423. }
  424. if len(parts) != 6 {
  425. p.conn.Close()
  426. return &ErrBadHeader{[]byte(header)}
  427. }
  428. // Parse out the remote address
  429. ip := net.ParseIP(parts[2])
  430. if ip == nil {
  431. p.conn.Close()
  432. return &ErrBadRemote{parts[2], parts[4]}
  433. }
  434. port, err := strconv.Atoi(parts[4])
  435. if err != nil {
  436. p.conn.Close()
  437. return &ErrBadRemote{parts[2], parts[4]}
  438. }
  439. p.remoteAddr = &net.TCPAddr{IP: ip, Port: port}
  440. // Parse out the destination address
  441. ip = net.ParseIP(parts[3])
  442. if ip == nil {
  443. p.conn.Close()
  444. return &ErrBadLocal{parts[3], parts[5]}
  445. }
  446. port, err = strconv.Atoi(parts[5])
  447. if err != nil {
  448. p.conn.Close()
  449. return &ErrBadLocal{parts[3], parts[5]}
  450. }
  451. p.localAddr = &net.TCPAddr{IP: ip, Port: port}
  452. return nil
  453. }