mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge 8f2bdfbddc
into a5049a8a13
This commit is contained in:
commit
6909e1fa2e
2 changed files with 38 additions and 64 deletions
|
@ -1556,7 +1556,6 @@ firewall:
|
||||||
- enable
|
- enable
|
||||||
- disable
|
- disable
|
||||||
- status
|
- status
|
||||||
- reload
|
|
||||||
nargs: "?"
|
nargs: "?"
|
||||||
default: status
|
default: status
|
||||||
--no-refresh:
|
--no-refresh:
|
||||||
|
|
101
src/firewall.py
101
src/firewall.py
|
@ -27,7 +27,11 @@ from moulinette.utils.log import getActionLogger
|
||||||
|
|
||||||
FIREWALL_FILE = "/etc/yunohost/firewall.yml"
|
FIREWALL_FILE = "/etc/yunohost/firewall.yml"
|
||||||
UPNP_CRON_JOB = "/etc/cron.d/yunohost-firewall-upnp"
|
UPNP_CRON_JOB = "/etc/cron.d/yunohost-firewall-upnp"
|
||||||
|
# A UDP port to use for the SSDP discovery phase of UPNP.
|
||||||
|
# Assigned by IANA to "Fujitsu ICL Terminal Emulator Program A", so no-one else is
|
||||||
|
# likely to use it (unlike port 1900 which is used by SSDP servers such
|
||||||
|
# as miniupnpd)
|
||||||
|
SSDP_CLIENT_PORT = 1901
|
||||||
logger = getActionLogger("yunohost.firewall")
|
logger = getActionLogger("yunohost.firewall")
|
||||||
|
|
||||||
|
|
||||||
|
@ -252,7 +256,7 @@ def firewall_reload(skip_upnp=False):
|
||||||
|
|
||||||
# Retrieve firewall rules and UPnP status
|
# Retrieve firewall rules and UPnP status
|
||||||
firewall = firewall_list(raw=True)
|
firewall = firewall_list(raw=True)
|
||||||
upnp = firewall_upnp()["enabled"] if not skip_upnp else False
|
upnp = firewall_upnp(no_refresh=True)["enabled"] if not skip_upnp else False
|
||||||
|
|
||||||
# IPv4
|
# IPv4
|
||||||
try:
|
try:
|
||||||
|
@ -354,66 +358,57 @@ def firewall_upnp(action="status", no_refresh=False):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
firewall = firewall_list(raw=True)
|
firewall = firewall_list(raw=True)
|
||||||
enabled = firewall["uPnP"]["enabled"]
|
|
||||||
|
|
||||||
# Compatibility with previous version
|
if action == "status":
|
||||||
if action == "reload":
|
enabled = firewall["uPnP"]["enabled"]
|
||||||
logger.debug("'reload' action is deprecated and will be removed")
|
elif action == "enable":
|
||||||
try:
|
|
||||||
# Remove old cron job
|
|
||||||
os.remove("/etc/cron.d/yunohost-firewall")
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
action = "status"
|
|
||||||
no_refresh = False
|
|
||||||
|
|
||||||
if action == "status" and no_refresh:
|
|
||||||
# Only return current state
|
|
||||||
return {"enabled": enabled}
|
|
||||||
elif action == "enable" or (enabled and action == "status"):
|
|
||||||
# Add cron job
|
# Add cron job
|
||||||
with open(UPNP_CRON_JOB, "w+") as f:
|
with open(UPNP_CRON_JOB, "w+") as f:
|
||||||
f.write(
|
f.write(
|
||||||
"*/50 * * * * root "
|
"*/12 * * * * root "
|
||||||
"/usr/bin/yunohost firewall upnp status >>/dev/null\n"
|
"/usr/bin/yunohost firewall upnp status >>/dev/null\n"
|
||||||
)
|
)
|
||||||
# Open port 1900 to receive discovery message
|
|
||||||
if 1900 not in firewall["ipv4"]["UDP"]:
|
|
||||||
firewall_allow("UDP", 1900, no_upnp=True, no_reload=True)
|
|
||||||
if not enabled:
|
|
||||||
firewall_reload(skip_upnp=True)
|
|
||||||
enabled = True
|
enabled = True
|
||||||
elif action == "disable" or (not enabled and action == "status"):
|
elif action == "disable":
|
||||||
try:
|
try:
|
||||||
# Remove cron job
|
# Remove cron job
|
||||||
os.remove(UPNP_CRON_JOB)
|
os.remove(UPNP_CRON_JOB)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
enabled = False
|
enabled = False
|
||||||
if action == "status":
|
|
||||||
no_refresh = True
|
|
||||||
else:
|
else:
|
||||||
raise YunohostValidationError("action_invalid", action=action)
|
raise YunohostValidationError("action_invalid", action=action)
|
||||||
|
|
||||||
# Refresh port mapping using UPnP
|
# Refresh port mapping
|
||||||
|
refresh_success = True
|
||||||
if not no_refresh:
|
if not no_refresh:
|
||||||
upnpc = miniupnpc.UPnP(localport=1)
|
# Open port to receive discovery message
|
||||||
|
process.run_commands(
|
||||||
|
["iptables -w -A INPUT -p udp --dport %d -j ACCEPT" % SSDP_CLIENT_PORT],
|
||||||
|
callback=_on_rule_command_error,
|
||||||
|
)
|
||||||
|
upnpc = miniupnpc.UPnP(localport=SSDP_CLIENT_PORT)
|
||||||
upnpc.discoverdelay = 3000
|
upnpc.discoverdelay = 3000
|
||||||
|
|
||||||
# Discover UPnP device(s)
|
# Discover UPnP device(s)
|
||||||
logger.debug("discovering UPnP devices...")
|
logger.debug("discovering UPnP devices...")
|
||||||
nb_dev = upnpc.discover()
|
nb_dev = upnpc.discover()
|
||||||
logger.debug("found %d UPnP device(s)", int(nb_dev))
|
logger.debug("found %d UPnP device(s)", int(nb_dev))
|
||||||
|
# Close discovery port
|
||||||
|
process.run_commands(
|
||||||
|
["iptables -w -D INPUT -p udp --dport %d -j ACCEPT" % SSDP_CLIENT_PORT],
|
||||||
|
callback=_on_rule_command_error,
|
||||||
|
)
|
||||||
|
|
||||||
if nb_dev < 1:
|
if nb_dev < 1:
|
||||||
logger.error(m18n.n("upnp_dev_not_found"))
|
logger.error(m18n.n("upnp_dev_not_found"))
|
||||||
enabled = False
|
refresh_success = False
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
# Select UPnP device
|
# Select UPnP device
|
||||||
upnpc.selectigd()
|
upnpc.selectigd()
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.debug("unable to select UPnP device", exc_info=1)
|
logger.debug("unable to select UPnP device", exc_info=1)
|
||||||
enabled = False
|
refresh_success = False
|
||||||
else:
|
else:
|
||||||
# Iterate over ports
|
# Iterate over ports
|
||||||
for protocol in ["TCP", "UDP"]:
|
for protocol in ["TCP", "UDP"]:
|
||||||
|
@ -430,7 +425,7 @@ def firewall_upnp(action="status", no_refresh=False):
|
||||||
upnpc.deleteportmapping(port, protocol)
|
upnpc.deleteportmapping(port, protocol)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
firewall["uPnP"][protocol + "_TO_CLOSE"] = []
|
del firewall["uPnP"][protocol + "_TO_CLOSE"]
|
||||||
|
|
||||||
for port in firewall["uPnP"][protocol]:
|
for port in firewall["uPnP"][protocol]:
|
||||||
if not isinstance(port, int):
|
if not isinstance(port, int):
|
||||||
|
@ -460,34 +455,17 @@ def firewall_upnp(action="status", no_refresh=False):
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"unable to add port %d using UPnP", port, exc_info=1
|
"unable to add port %d using UPnP", port, exc_info=1
|
||||||
)
|
)
|
||||||
enabled = False
|
refresh_success = False
|
||||||
|
if refresh_success:
|
||||||
|
logger.debug("UPnP port refresh successful")
|
||||||
|
if action == "enable":
|
||||||
|
logger.success(m18n.n("upnp_enabled"))
|
||||||
|
elif action == "disable":
|
||||||
|
logger.success(m18n.n("upnp_disabled"))
|
||||||
|
|
||||||
_update_firewall_file(firewall)
|
# Save state always (note that refreshing can change the "TO_CLOSE" states)
|
||||||
|
firewall["uPnP"]["enabled"] = enabled
|
||||||
if enabled != firewall["uPnP"]["enabled"]:
|
_update_firewall_file(firewall)
|
||||||
firewall = firewall_list(raw=True)
|
|
||||||
firewall["uPnP"]["enabled"] = enabled
|
|
||||||
|
|
||||||
_update_firewall_file(firewall)
|
|
||||||
|
|
||||||
if not no_refresh:
|
|
||||||
# Display success message if needed
|
|
||||||
if action == "enable" and enabled:
|
|
||||||
logger.success(m18n.n("upnp_enabled"))
|
|
||||||
elif action == "disable" and not enabled:
|
|
||||||
logger.success(m18n.n("upnp_disabled"))
|
|
||||||
# Make sure to disable UPnP
|
|
||||||
elif action != "disable" and not enabled:
|
|
||||||
firewall_upnp("disable", no_refresh=True)
|
|
||||||
|
|
||||||
if not enabled and (action == "enable" or 1900 in firewall["ipv4"]["UDP"]):
|
|
||||||
# Close unused port 1900
|
|
||||||
firewall_disallow("UDP", 1900, no_reload=True)
|
|
||||||
if not no_refresh:
|
|
||||||
firewall_reload(skip_upnp=True)
|
|
||||||
|
|
||||||
if action == "enable" and not enabled:
|
|
||||||
raise YunohostError("upnp_port_open_failed")
|
|
||||||
return {"enabled": enabled}
|
return {"enabled": enabled}
|
||||||
|
|
||||||
|
|
||||||
|
@ -509,9 +487,6 @@ def firewall_stop():
|
||||||
os.system("ip6tables -F")
|
os.system("ip6tables -F")
|
||||||
os.system("ip6tables -X")
|
os.system("ip6tables -X")
|
||||||
|
|
||||||
if os.path.exists(UPNP_CRON_JOB):
|
|
||||||
firewall_upnp("disable")
|
|
||||||
|
|
||||||
|
|
||||||
def _get_ssh_port(default=22):
|
def _get_ssh_port(default=22):
|
||||||
"""Return the SSH port to use
|
"""Return the SSH port to use
|
||||||
|
|
Loading…
Add table
Reference in a new issue