1
- #!/usr/bin/python
1
+ #!/usr/bin/env python3
2
2
3
3
"""Libvirt port-forwarding hook.
4
4
@@ -15,8 +15,7 @@ import re
15
15
import subprocess
16
16
import sys
17
17
18
- # python 2.6 support
19
- if "check_output" not in dir ( subprocess ):
18
+ if "check_output" not in dir (subprocess ):
20
19
def f (* popenargs , ** kwargs ):
21
20
if 'stdout' in kwargs :
22
21
raise ValueError ('stdout argument not allowed, it will be overridden.' )
@@ -61,6 +60,10 @@ def json_minify(string, strip_space=True):
61
60
# replace white space as defined in standard
62
61
tmp = re .sub ('[ \t \n \r ]+' , '' , tmp )
63
62
new_str .append (tmp )
63
+ elif not strip_space :
64
+ # Replace comments with white space so that the JSON parser reports
65
+ # the correct column numbers on parsing errors.
66
+ new_str .append (' ' * (match .start () - index ))
64
67
65
68
index = match .end ()
66
69
val = match .group ()
@@ -79,11 +82,19 @@ def json_minify(string, strip_space=True):
79
82
in_single = True
80
83
elif val == '*/' and in_multi and not (in_string or in_single ):
81
84
in_multi = False
85
+ if not strip_space :
86
+ new_str .append (' ' * len (val ))
82
87
elif val in '\r \n ' and not (in_multi or in_string ) and in_single :
83
88
in_single = False
84
89
elif not ((in_multi or in_single ) or (val in ' \r \n \t ' and strip_space )): # noqa
85
90
new_str .append (val )
86
91
92
+ if not strip_space :
93
+ if val in '\r \n ' :
94
+ new_str .append (val )
95
+ elif in_multi or in_single :
96
+ new_str .append (' ' * len (val ))
97
+
87
98
new_str .append (string [index :])
88
99
return '' .join (new_str )
89
100
@@ -156,6 +167,8 @@ def populate_chains(dnat_chain, snat_chain, fwd_chain, public_ip, private_ip, do
156
167
subprocess .call ([IPTABLES_BINARY , "-t" , "nat" , "-A" , dnat_chain , "-p" , protocol ,
157
168
"-d" , public_ip , "--dport" , str (public_port ), "-j" , "DNAT" , "--to" , dest ] +
158
169
(["-s" , source_ip ] if source_ip else []))
170
+ subprocess .call ([IPTABLES_BINARY , "-t" , "nat" , "-A" , snat_chain , "-p" , protocol ,
171
+ "-s" , private_ip , "--dport" , str (private_port ), "-j" , "SNAT" , "--to-source" , public_ip ])
159
172
subprocess .call ([IPTABLES_BINARY , "-t" , "nat" , "-A" , snat_chain , "-p" , protocol ,
160
173
"-s" , private_ip , "-d" , private_ip , "--dport" , str (public_port ), "-j" , "MASQUERADE" ])
161
174
interface = ["-o" , domain ["interface" ]
@@ -172,6 +185,8 @@ def populate_chains(dnat_chain, snat_chain, fwd_chain, public_ip, private_ip, do
172
185
private_ip , ports_range .replace (":" , "-" , 1 ))
173
186
subprocess .call ([IPTABLES_BINARY , "-t" , "nat" , "-A" , dnat_chain , "-p" , port_range ["protocol" ],
174
187
"-d" , public_ip , "--dport" , ports_range , "-j" , "DNAT" , "--to" , dest ])
188
+ subprocess .call ([IPTABLES_BINARY , "-t" , "nat" , "-A" , snat_chain , "-p" , port_range ["protocol" ],
189
+ "-s" , private_ip , "--dport" , str (private_port ), "-j" , "SNAT" , "--to-source" , public_ip ])
175
190
subprocess .call ([IPTABLES_BINARY , "-t" , "nat" , "-A" , snat_chain , "-p" , port_range ["protocol" ],
176
191
"-s" , private_ip , "-d" , private_ip , "--dport" , ports_range , "-j" , "MASQUERADE" ])
177
192
interface = ["-o" , domain ["interface" ]
@@ -186,12 +201,16 @@ def insert_chains(action, dnat_chain, snat_chain, fwd_chain, public_ip, private_
186
201
"OUTPUT" , "-d" , public_ip , "-j" , dnat_chain ])
187
202
subprocess .call ([IPTABLES_BINARY , "-t" , "nat" , action ,
188
203
"PREROUTING" , "-d" , public_ip , "-j" , dnat_chain ])
204
+ # TODO: Find solution for connections from different private_ip to public_ip
205
+ # maybe use private_ip_net as source instead
206
+ # WORKAROUND: remove `"-s", private_ip, `
189
207
subprocess .call ([IPTABLES_BINARY , "-t" , "nat" , action , "POSTROUTING" ,
190
208
"-s" , private_ip , "-d" , private_ip , "-j" , snat_chain ])
191
209
subprocess .call ([IPTABLES_BINARY , "-t" , "filter" , action ,
192
210
"FORWARD" , "-d" , private_ip , "-j" , fwd_chain ])
193
211
194
212
# the snat_chain doesn't work unless we turn off filtering bridged packets
213
+ # https://wiki.libvirt.org/page/Net.bridge.bridge-nf-call_and_sysctl.conf
195
214
196
215
197
216
def disable_bridge_filtering ():
0 commit comments