Changeset 370 in code for trunk


Ignore:
Timestamp:
Jul 22, 2020, 3:03:01 PM (5 years ago)
Author:
contact
Message:

Add accept-proxy-ip config directive

This allows to set the list of IPs allowed to act as a proxy. This is
only used for WebSockets right now, but will be expanded to TCP as well
once the PROXY protocol is supported.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/config/config.go

    r323 r370  
    55        "fmt"
    66        "io"
     7        "net"
    78        "os"
    89
    910        "github.com/google/shlex"
    1011)
     12
     13type IPSet []*net.IPNet
     14
     15func (set IPSet) Contains(ip net.IP) bool {
     16        for _, n := range set {
     17                if n.Contains(ip) {
     18                        return true
     19                }
     20        }
     21        return false
     22}
     23
     24// loopbackIPs contains the loopback networks 127.0.0.0/8 and ::1/128.
     25var loopbackIPs = IPSet{
     26        &net.IPNet{
     27                IP:   net.IP{127, 0, 0, 0},
     28                Mask: net.CIDRMask(8, 32),
     29        },
     30        &net.IPNet{
     31                IP:   net.IPv6loopback,
     32                Mask: net.CIDRMask(128, 128),
     33        },
     34}
    1135
    1236type TLS struct {
     
    1539
    1640type Server struct {
    17         Listen      []string
    18         Hostname    string
    19         TLS         *TLS
    20         SQLDriver   string
    21         SQLSource   string
    22         LogPath     string
    23         HTTPOrigins []string
     41        Listen         []string
     42        Hostname       string
     43        TLS            *TLS
     44        SQLDriver      string
     45        SQLSource      string
     46        LogPath        string
     47        HTTPOrigins    []string
     48        AcceptProxyIPs IPSet
    2449}
    2550
     
    3055        }
    3156        return &Server{
    32                 Hostname:  hostname,
    33                 SQLDriver: "sqlite3",
    34                 SQLSource: "soju.db",
     57                Hostname:       hostname,
     58                SQLDriver:      "sqlite3",
     59                SQLSource:      "soju.db",
     60                AcceptProxyIPs: loopbackIPs,
    3561        }
    3662}
     
    94120                case "http-origin":
    95121                        srv.HTTPOrigins = append(srv.HTTPOrigins, d.Params...)
     122                case "accept-proxy-ip":
     123                        srv.AcceptProxyIPs = nil
     124                        for _, s := range d.Params {
     125                                _, n, err := net.ParseCIDR(s)
     126                                if err != nil {
     127                                        return nil, fmt.Errorf("directive %q: failed to parse CIDR: %v", d.Name, err)
     128                                }
     129                                srv.AcceptProxyIPs = append(srv.AcceptProxyIPs, n)
     130                        }
    96131                default:
    97132                        return nil, fmt.Errorf("unknown directive %q", d.Name)
  • trunk/doc/soju.1.scd

    r369 r370  
    110110        interpreted as shell patterns, see *glob*(7).
    111111
     112*accept-proxy-ip* <cidr...>
     113        Allow the specified IPs to act as a proxy. Proxys have the ability to
     114        overwrite the remote and local connection addresses (via the X-Forwarded-*
     115        HTTP header fields). By default, the loopback addresses 127.0.0.0/8 and
     116        ::1/128 are accepted.
     117
    112118# IRC SERVICE
    113119
  • trunk/server.go

    r348 r370  
    1212        "gopkg.in/irc.v3"
    1313        "nhooyr.io/websocket"
     14
     15        "git.sr.ht/~emersion/soju/config"
    1416)
    1517
     
    4244
    4345type Server struct {
    44         Hostname     string
    45         Logger       Logger
    46         RingCap      int
    47         HistoryLimit int
    48         LogPath      string
    49         Debug        bool
    50         HTTPOrigins  []string
     46        Hostname       string
     47        Logger         Logger
     48        RingCap        int
     49        HistoryLimit   int
     50        LogPath        string
     51        Debug          bool
     52        HTTPOrigins    []string
     53        AcceptProxyIPs config.IPSet
    5154
    5255        db *DB
     
    154157        }
    155158
    156         isLoopback := false
     159        isProxy := false
    157160        if host, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
    158161                if ip := net.ParseIP(host); ip != nil {
    159                         isLoopback = ip.IsLoopback()
     162                        isProxy = s.AcceptProxyIPs.Contains(ip)
    160163                }
    161164        }
    162165
    163         // Only trust X-Forwarded-* header fields if this is a loopback connection,
     166        // Only trust X-Forwarded-* header fields if this is a trusted proxy IP
    164167        // to prevent users from spoofing the remote address
    165168        remoteAddr := req.RemoteAddr
    166169        forwardedHost := req.Header.Get("X-Forwarded-For")
    167170        forwardedPort := req.Header.Get("X-Forwarded-Port")
    168         if isLoopback && forwardedHost != "" && forwardedPort != "" {
     171        if isProxy && forwardedHost != "" && forwardedPort != "" {
    169172                remoteAddr = net.JoinHostPort(forwardedHost, forwardedPort)
    170173        }
Note: See TracChangeset for help on using the changeset viewer.