diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2020-03-25 13:44:40 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2020-03-25 13:48:56 +0200 |
commit | e801d94e40f23c09f27a807fec48fc0133ddb1c6 (patch) | |
tree | a7cae42d7f81c4becddecdf69fc854a42e81e555 | |
parent | a6d6598a99f654cf25a65e512ce7bf4856fda3b2 (diff) | |
download | vmod-remoteip-e801d94e40f23c09f27a807fec48fc0133ddb1c6.tar.gz vmod-remoteip-e801d94e40f23c09f27a807fec48fc0133ddb1c6.tar.bz2 |
Use ACL to hold IPs of the trusted proxies.v2.0
Suggested by Dridi Boukelmoune.
-rw-r--r-- | NEWS | 9 | ||||
-rw-r--r-- | README | 11 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/vmod_remoteip.c | 313 | ||||
-rw-r--r-- | src/vmod_remoteip.vcc | 34 | ||||
-rw-r--r-- | tests/ipv4found.at | 8 | ||||
-rw-r--r-- | tests/ipv4notfound.at | 8 | ||||
-rw-r--r-- | tests/ipv6found.at | 8 | ||||
-rw-r--r-- | tests/ipv6notfound.at | 8 |
9 files changed, 66 insertions, 335 deletions
@@ -1,8 +1,15 @@ | |||
1 | vmod_remoteip -- history of user-visible changes. 2020-03-21 | 1 | vmod_remoteip -- history of user-visible changes. 2020-03-25 |
2 | See the end of file for copying conditions. | 2 | See the end of file for copying conditions. |
3 | 3 | ||
4 | Please send vmod_remoteip bug reports to <gray@gnu.org> | 4 | Please send vmod_remoteip bug reports to <gray@gnu.org> |
5 | 5 | ||
6 | Version 2.0, 2020-03-25 | ||
7 | |||
8 | * Use ACL to hold IPs of the trusted proxies. | ||
9 | |||
10 | The ACL name is passed as the first argument to the remoteip.get | ||
11 | function. The remoteip.init function is now gone. | ||
12 | |||
6 | Version 1.0, 2020-03-21 | 13 | Version 1.0, 2020-03-21 |
7 | 14 | ||
8 | Initial release | 15 | Initial release |
@@ -20,10 +20,11 @@ hosts from the ACL "allowed": | |||
20 | #+BEGIN_SRC vcl-script | 20 | #+BEGIN_SRC vcl-script |
21 | import std; | 21 | import std; |
22 | import remoteip; | 22 | import remoteip; |
23 | 23 | ||
24 | sub vcl_init { | 24 | // Register trusted proxy server addresses |
25 | // Register trusted proxy server addresses | 25 | acl trusted { |
26 | remoteip.init("192.0.2.1, 127.0.0.1"); | 26 | "192.0.2.1"; |
27 | "127.0.0.1"; | ||
27 | } | 28 | } |
28 | 29 | ||
29 | acl allowed { | 30 | acl allowed { |
@@ -32,7 +33,7 @@ hosts from the ACL "allowed": | |||
32 | } | 33 | } |
33 | 34 | ||
34 | sub vcl_recv { | 35 | sub vcl_recv { |
35 | set req.http.x-real-ip = remoteip.get(req.http.X-Forwarded-For); | 36 | set req.http.x-real-ip = remoteip.get(trusted, req.http.X-Forwarded-For); |
36 | if (std.ip(req.http.x-real-ip) ~ allowed) { | 37 | if (std.ip(req.http.x-real-ip) ~ allowed) { |
37 | ... | 38 | ... |
38 | } | 39 | } |
diff --git a/configure.ac b/configure.ac index cc8480a..1fcc3bc 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -15,7 +15,7 @@ | |||
15 | # along with vmod_remoteip. If not, see <http://www.gnu.org/licenses/>. | 15 | # along with vmod_remoteip. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | ||
17 | AC_PREREQ(2.69) | 17 | AC_PREREQ(2.69) |
18 | AC_INIT([vmod-remoteip], [1.0], [gray@gnu.org]) | 18 | AC_INIT([vmod-remoteip], [2.0], [gray@gnu.org]) |
19 | AC_CONFIG_AUX_DIR([build-aux]) | 19 | AC_CONFIG_AUX_DIR([build-aux]) |
20 | AC_CONFIG_MACRO_DIR([m4]) | 20 | AC_CONFIG_MACRO_DIR([m4]) |
21 | AC_CONFIG_SRCDIR(src/vmod_remoteip.vcc) | 21 | AC_CONFIG_SRCDIR(src/vmod_remoteip.vcc) |
diff --git a/src/vmod_remoteip.c b/src/vmod_remoteip.c index 528b0a4..8bba147 100644 --- a/src/vmod_remoteip.c +++ b/src/vmod_remoteip.c | |||
@@ -26,314 +26,43 @@ | |||
26 | #include <cache/cache.h> | 26 | #include <cache/cache.h> |
27 | #include <vcl.h> | 27 | #include <vcl.h> |
28 | #include <vcc_if.h> | 28 | #include <vcc_if.h> |
29 | #include <vqueue.h> | 29 | #include <vsa.h> |
30 | #ifdef VPFX | ||
31 | # define VEVENT(a) VPFX(a) | ||
32 | #else | ||
33 | /* For compatibility with varnish prior to 6.2 */ | ||
34 | # define VEVENT(a) a | ||
35 | #endif | ||
36 | |||
37 | /* Max. number of bytes in an IPv6 address */ | ||
38 | #define MU_INADDR_BYTES 16 | ||
39 | |||
40 | /* CIDR representation */ | ||
41 | struct cidr { | ||
42 | int family; /* Address family */ | ||
43 | int len; /* Number of bytes in the address */ | ||
44 | unsigned char address[MU_INADDR_BYTES]; | ||
45 | unsigned char netmask[MU_INADDR_BYTES]; | ||
46 | VSLIST_ENTRY(cidr) next; | ||
47 | }; | ||
48 | |||
49 | typedef VSLIST_HEAD(,cidr) CIDRHEAD; | ||
50 | |||
51 | /* Returns 1 if ADDR is a valid string representation of IPv4 address */ | ||
52 | static int | ||
53 | str_is_ipv4(const char *addr, size_t len) | ||
54 | { | ||
55 | int dot_count = 0; | ||
56 | int digit_count = 0; | ||
57 | |||
58 | for (; len; addr++, len--) { | ||
59 | if (!isascii(*addr)) | ||
60 | return 0; | ||
61 | if (*addr == '.') { | ||
62 | if (++dot_count > 3) | ||
63 | break; | ||
64 | digit_count = 0; | ||
65 | } | ||
66 | else if (!(isdigit(*addr) && ++digit_count <= 3)) | ||
67 | return 0; | ||
68 | } | ||
69 | return (dot_count == 3); | ||
70 | } | ||
71 | |||
72 | #define PFXSTR_IPV4_MAPPED "::ffff:" | ||
73 | #define PFXLEN_IPV4_MAPPED (sizeof PFXSTR_IPV4_MAPPED - 1) | ||
74 | |||
75 | static int | ||
76 | str_is_ipv4mapped(const char *addr, size_t len) | ||
77 | { | ||
78 | return len > PFXLEN_IPV4_MAPPED | ||
79 | && strncasecmp(PFXSTR_IPV4_MAPPED, addr, PFXLEN_IPV4_MAPPED) | ||
80 | == 0 | ||
81 | && str_is_ipv4(addr + PFXLEN_IPV4_MAPPED, len - PFXLEN_IPV4_MAPPED); | ||
82 | } | ||
83 | |||
84 | /* Returns 1 if ADDR is a valid IPv6 address */ | ||
85 | static int | ||
86 | str_is_ipv6(const char *addr, size_t len) | ||
87 | { | ||
88 | int col_count = 0; /* Number of colons */ | ||
89 | int dcol = 0; /* Did we encounter a double-colon? */ | ||
90 | int dig_count = 0; /* Number of digits in the last group */ | ||
91 | |||
92 | for (; len; addr++, len--) { | ||
93 | if (!isascii (*addr)) | ||
94 | return 0; | ||
95 | else if (isxdigit(*addr)) { | ||
96 | if (++dig_count > 4) | ||
97 | return 0; | ||
98 | } else if (*addr == ':') { | ||
99 | if (col_count && dig_count == 0 && ++dcol > 1) | ||
100 | return 0; | ||
101 | if (++col_count > 7) | ||
102 | return 0; | ||
103 | dig_count = 0; | ||
104 | } | ||
105 | else | ||
106 | return 0; | ||
107 | } | ||
108 | return (col_count == 7 || dcol); | ||
109 | } | ||
110 | |||
111 | static void | ||
112 | uint32_to_bytes(unsigned char *bytes, uint32_t u) | ||
113 | { | ||
114 | int i; | ||
115 | |||
116 | for (i = 0; i < 4; i++) { | ||
117 | bytes[i] = u & 0xff; | ||
118 | u >>= 8; | ||
119 | } | ||
120 | } | ||
121 | 30 | ||
122 | static int | 31 | static int |
123 | inaddr_to_bytes(int af, void *buf, unsigned char *bytes) | 32 | is_trusted_ip(VRT_CTX, VCL_ACL acl, char const *ipstr) |
124 | { | ||
125 | uint32_t u; | ||
126 | |||
127 | switch (af) { | ||
128 | case AF_INET: | ||
129 | memcpy(&u, buf, sizeof u); | ||
130 | uint32_to_bytes(bytes, u); | ||
131 | return 4; | ||
132 | |||
133 | case AF_INET6: | ||
134 | memcpy(bytes, buf, 16); | ||
135 | return 16; | ||
136 | } | ||
137 | |||
138 | abort(); | ||
139 | } | ||
140 | |||
141 | /* Fill in the BUF (LEN bytes long) with a network mask corresponding to | ||
142 | the mask length MASKLEN */ | ||
143 | static void | ||
144 | masklen_to_netmask(unsigned char *buf, size_t len, size_t masklen) | ||
145 | { | ||
146 | int i, cnt; | ||
147 | |||
148 | cnt = masklen / 8; | ||
149 | for (i = 0; i < cnt; i++) | ||
150 | buf[i] = 0xff; | ||
151 | if (i == len) | ||
152 | return; | ||
153 | cnt = 8 - masklen % 8; | ||
154 | buf[i++] = (0xff >> cnt) << cnt; | ||
155 | for (; i < len; i++) | ||
156 | buf[i] = 0; | ||
157 | } | ||
158 | |||
159 | #define CIDR_MAXBUFSIZE 81 | ||
160 | |||
161 | /* Convert string STR to CIDR. Return 0 on success and -1 on failure. */ | ||
162 | static int | ||
163 | str_to_cidr(char const *str, struct cidr *cidr, char **endp) | ||
164 | { | 33 | { |
34 | struct addrinfo hints; | ||
35 | struct addrinfo *res; | ||
36 | struct suckaddr *ip; | ||
165 | int rc; | 37 | int rc; |
166 | char *ipbuf, *ipstart; | ||
167 | union { | ||
168 | struct in_addr in; | ||
169 | struct in6_addr in6; | ||
170 | } inaddr; | ||
171 | size_t len; | ||
172 | |||