Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 149 lines (115 sloc) 3.661 kb
d468e0d @klacke added support/docs for authbind/privbind
authored
1
2 <erl>
3 out(A) ->
4 {ssi, "TAB.inc", "%%",[{"privbind", "choosen"}]}.
5 </erl>
6
7
8 <div id="entry">
9
10 <h1>Binding to priviliged ports</h1>
11
12 <p>
13 A common misfeature found on UN*X operating systems is the
14 restriction that only root can bind to ports below 1024.
15 Many a dollar has been wasted on workarounds and -often- the results are
16 security holes.
17
18 </p>
19 <p>
20 Both FreeBSD and Solaris have elegant configuration options to
21 turn this feature off. On FreeBSD:
22
23 <div class="box">
24 <verbatim>
25 $ sysctl net.inet.ip.portrange.reservedhigh=0
26 </verbatim>
27 </div>
28
29 the above is best added to your /etc/sysctl.conf
30 </p>
31 <p>
32 Similarly on Solaris we can just configure away this misfeature.
33 Assuming we want to run Yaws/SSL under a non-root user "erlang" on
34 ports 80/443.
35 </p>
36 <p>
37 On Solaris we can do that easily by granting the specific right to bind
38 privileged ports <1024 (and only that) to "erlang" using:
39 </p>
40
41 <div class="box">
42 <verbatim>
43 $ /usr/sbin/usermod -K defaultpriv=basic,net_privaddr erlang
44 </verbatim>
45 </div>
46
47 <p>
48 And check the we get what we want through:
49 </p>
50
51
52 <div class="box">
53 <verbatim>
54 $ grep erlang /etc/user_attr
55 erlang::::type=normal;defaultpriv=basic,net_privaddr
56
57 </verbatim>
58 </div>
59
60
61 <p>
62 Linux doesn't have anything like the above. There are a couple
63 of options on Linux. The best is to use an auxiliary program
64 like authbind <em>http://packages.debian.org/stable/authbind</em>
65 or privbind <em>http://sourceforge.net/projects/privbind/</em>
66 </p>
67 <p>
68 These programs are run by root. Yaws writes its temporary
69 JIT compiled files in $HOME/.yaws and this doesn't work that
70 well with authbind/privbind. A non root user will try to
71 write in /root/.yaws. The solution to this is to set the
72 environment variable YAWSHOME. Yaws will then consider that to
73 be HOME rather that $HOME.
74 </p>
75 <p>
76 To start yaws under e.g authbind we can do:
77 </p>
78
79
80 <div class="box">
81 <verbatim>
82 $ sudo YAWSHOME=/tmp/abc privbind -u klacke /home/klacke/bin/yaws \
83 -c /home/klacke/yaws.conf -i
84
85 </verbatim>
86 </div>
87
88 <p>
89 The above command starts yaws as user <em>klacke</em> and bind
90 to ports below 1024
91 </p>
92
93 <p>
94 Yet another option is to is to install fdsrv which is a standalone
95 program that has the suid bit set, binds priviliged ports and passes
96 the filedescriptor to yaws. I have made a package out of the jungerl
97 code that can be easily installed just through the usual cycle of
98 make && make install The code is at
99 </p>
100 <pre>
101 http://yaws.hyber.org/download/fd_server-2.3.0.tgz
102 </pre>
103 <p>
104 One major drawback with fdsrv is that it doesn't work for SSL. With
105 the case of SSL, one possible solution is to put ssltunnel in
106 front of yaws and let yaws bind to 127.0.0.1
107 </p>
108 <p>
109 All in all the fdsrv option is much worse that the authbind option.
110 </p>
111
112 <p>
113
114 Yet another (more complicated way) for linux users is to hack the kernel.
115 Here is a patch I did for some version of the 2.6 series kernels .. you get the idea.
116 </p>
117
118
119 <verbatim>
120 [root@lax]ipv4 > diff -c af_inet.c*
121 *** af_inet.c Wed Feb 23 23:31:35 2005
122 --- af_inet.c~ Thu Feb 17 18:13:13 2005
123 ***************
124 *** 423,434 ****
125
126 snum = ntohs(addr->sin_port);
127 err = -EACCES;
128 - #if 0
129 - /* removed by klacke */
130 if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
131 goto out;
132 - #endif
133 -
134
135 /* We keep a pair of addresses. rcv_saddr is the one
136 * used by hash lookups, and saddr is used for transmit.
137 --- 423,430 ----
138 </verbatim>
139
140
141
142
143
144 <erl>
145 out(A) -> {ssi, "END2",[],[]}.
146 </erl>
147
148
Something went wrong with that request. Please try again.