mirror of
https://github.com/RaspAP/raspap-webgui.git
synced 2024-11-25 00:50:29 +00:00
Merge pull request #49 from RaspAP/feature-firewall
Feature: firewall settings
This commit is contained in:
commit
d0564ec946
11 changed files with 823 additions and 2 deletions
|
@ -24,12 +24,14 @@ define('RASPI_OPENVPN_CLIENT_CONFIG', '/etc/openvpn/client/client.conf');
|
|||
define('RASPI_OPENVPN_CLIENT_LOGIN', '/etc/openvpn/client/login.conf');
|
||||
define('RASPI_WIREGUARD_PATH', '/etc/wireguard/');
|
||||
define('RASPI_WIREGUARD_CONFIG', RASPI_WIREGUARD_PATH.'wg0.conf');
|
||||
define('RASPI_FIREWALL_CONF', RASPI_CONFIG.'/networking/firewall/firewall.conf');
|
||||
define('RASPI_IPTABLES_CONF', RASPI_CONFIG.'/networking/firewall/iptables_rules.json');
|
||||
define('RASPI_TORPROXY_CONFIG', '/etc/tor/torrc');
|
||||
define('RASPI_LIGHTTPD_CONFIG', '/etc/lighttpd/lighttpd.conf');
|
||||
define('RASPI_ACCESS_CHECK_IP', '1.1.1.1');
|
||||
define('RASPI_ACCESS_CHECK_DNS', 'one.one.one.one');
|
||||
define('RASPI_CLIENT_CONFIG_PATH', '/etc/raspap/networking/client_udev_prototypes.json');
|
||||
define('RASPI_MOBILEDATA_CONFIG', '/etc/raspap/networking/mobiledata.ini');
|
||||
define('RASPI_CLIENT_CONFIG_PATH', RASPI_CONFIG.'/networking/client_udev_prototypes.json');
|
||||
define('RASPI_MOBILEDATA_CONFIG', RASPI_CONFIG.'/networking/mobiledata.ini');
|
||||
define('RASPI_CLIENT_SCRIPT_PATH', '/usr/local/sbin');
|
||||
|
||||
// Constant for the 5GHz wireless regulatory domain
|
||||
|
@ -44,6 +46,7 @@ define('RASPI_DHCP_ENABLED', true);
|
|||
define('RASPI_ADBLOCK_ENABLED', false);
|
||||
define('RASPI_OPENVPN_ENABLED', false);
|
||||
define('RASPI_WIREGUARD_ENABLED', false);
|
||||
define('RASPI_FIREWALL_ENABLED', true);
|
||||
define('RASPI_TORPROXY_ENABLED', false);
|
||||
define('RASPI_CONFAUTH_ENABLED', true);
|
||||
define('RASPI_CHANGETHEME_ENABLED', true);
|
||||
|
|
205
config/iptables_rules.json
Normal file
205
config/iptables_rules.json
Normal file
|
@ -0,0 +1,205 @@
|
|||
{
|
||||
"info": "IPTABLES rules. $...$ expressions will be replaces automatically ($INTERFACE$, $PORT$, $IPADDRESS$)",
|
||||
"rules_v4_file": "/etc/iptables/rules.v4",
|
||||
"rules_v6_file": "/etc/iptables/rules.v6",
|
||||
"order": [ "pre_rules", "restriction_rules", "main_rules", "exception_rules" ],
|
||||
"pre_rules": [
|
||||
{
|
||||
"name": "firewall policies",
|
||||
"fw-state": true,
|
||||
"comment": "Policy rules (firewall)",
|
||||
"rules": [
|
||||
"-P INPUT DROP",
|
||||
"-P FORWARD ACCEPT",
|
||||
"-P OUTPUT ACCEPT",
|
||||
"-t nat -P PREROUTING ACCEPT",
|
||||
"-t nat -P POSTROUTING ACCEPT",
|
||||
"-t nat -P INPUT ACCEPT",
|
||||
"-t nat -P OUTPUT ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "policies",
|
||||
"fw-state": false,
|
||||
"comment": "Policy rules",
|
||||
"rules": [
|
||||
"-P INPUT ACCEPT",
|
||||
"-P FORWARD ACCEPT",
|
||||
"-P OUTPUT ACCEPT",
|
||||
"-t nat -P PREROUTING ACCEPT",
|
||||
"-t nat -P POSTROUTING ACCEPT",
|
||||
"-t nat -P INPUT ACCEPT",
|
||||
"-t nat -P OUTPUT ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "loopback",
|
||||
"fw-state": true,
|
||||
"comment": "allow loopback device",
|
||||
"rules": [
|
||||
"-A INPUT -i lo -j ACCEPT",
|
||||
"-A OUTPUT -o lo -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ping",
|
||||
"fw-state": true,
|
||||
"ip-version": 4,
|
||||
"comment": "allow ping request and echo",
|
||||
"rules": [
|
||||
"-A INPUT -p icmp --icmp-type 8/0 -j ACCEPT",
|
||||
"-A INPUT -p icmp --icmp-type 0/0 -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ping IPv6",
|
||||
"fw-state": true,
|
||||
"ip-version": 6,
|
||||
"comment": "allow ping request and echo for IPv6",
|
||||
"rules": [
|
||||
"-A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT",
|
||||
"-A INPUT -p icmpv6 --icmpv6-type echo-reply -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ntp",
|
||||
"fw-state": true,
|
||||
"comment": "allow ntp request via udp (tcp should work w/o rule)",
|
||||
"rules": [
|
||||
"-A INPUT -p udp --sport 123 -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "dns",
|
||||
"fw-state": true,
|
||||
"comment": "allow dns request via tcp and udp",
|
||||
"rules": [
|
||||
"-A INPUT -p udp -m multiport --sport 53,853 -j ACCEPT",
|
||||
"-A INPUT -p tcp -m multiport --sport 53,853 -j ACCEPT"
|
||||
]
|
||||
}
|
||||
],
|
||||
"main_rules": [
|
||||
{
|
||||
"name": "accesspoint",
|
||||
"fw-state": true,
|
||||
"comment": "Access point interface by default no restrictions",
|
||||
"dependson": [
|
||||
{ "var": "ap-device", "type": "string", "replace": "$INTERFACE$" }
|
||||
],
|
||||
"rules": [
|
||||
"-A INPUT -i $INTERFACE$ -j ACCEPT",
|
||||
"-A OUTPUT -o $INTERFACE$ -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "NAT for access point",
|
||||
"comment": "Masquerading needed for access point",
|
||||
"rules": [
|
||||
"-t nat -A POSTROUTING -j MASQUERADE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "clients",
|
||||
"fw-state": true,
|
||||
"comment": "Rules for client interfaces (includes tun device)",
|
||||
"rules": [
|
||||
"-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "openvpn",
|
||||
"comment": "Rules for tunnel device (tun)",
|
||||
"ip-version": 4,
|
||||
"dependson": [
|
||||
{ "var": "openvpn-enable", "type": "bool" },
|
||||
{ "var": "openvpn-serverip", "type": "string", "replace": "$IPADDRESS$" },
|
||||
{ "var": "ap-device", "type": "string", "replace": "$INTERFACE$" }
|
||||
],
|
||||
"rules": [
|
||||
"-A INPUT -p udp -s $IPADDRESS$ -j ACCEPT",
|
||||
"-A FORWARD -i tun+ -o $INTERFACE$ -m state --state RELATED,ESTABLISHED -j ACCEPT",
|
||||
"-A FORWARD -i $INTERFACE$ -o tun+ -j ACCEPT",
|
||||
"-t nat -A POSTROUTING -o tun+ -j MASQUERADE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "wireguard",
|
||||
"comment": "Rules for wireguard device (wg)",
|
||||
"ip-version": 4,
|
||||
"dependson": [
|
||||
{ "var": "wireguard-enable", "type": "bool" },
|
||||
{ "var": "wireguard-serverip", "type": "string", "replace": "$IPADDRESS$" },
|
||||
{ "var": "client-device", "type": "string", "replace": "$INTERFACE$" }
|
||||
],
|
||||
"rules": [
|
||||
"-A INPUT -p udp -s $IPADDRESS$ -j ACCEPT",
|
||||
"-A FORWARD -i wg+ -j ACCEPT",
|
||||
"-t nat -A POSTROUTING -o $INTERFACE$ -j MASQUERADE"
|
||||
]
|
||||
}
|
||||
],
|
||||
"exception_rules": [
|
||||
{
|
||||
"name": "ssh",
|
||||
"fw-state": true,
|
||||
"comment": "Allow ssh access to RaspAP on port 22",
|
||||
"dependson": [
|
||||
{ "var": "ssh-enable", "type": "bool" }
|
||||
],
|
||||
"rules": [
|
||||
"-A INPUT -p tcp --dport 22 -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "http",
|
||||
"fw-state": true,
|
||||
"comment": "Allow access to RaspAP GUI (https)",
|
||||
"dependson": [
|
||||
{ "var": "http-enable", "type": "bool" }
|
||||
],
|
||||
"rules": [
|
||||
"-A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "interface",
|
||||
"fw-state": true,
|
||||
"comment": "Exclude interface from firewall",
|
||||
"dependson": [
|
||||
{ "var": "excl-devices", "type": "list", "replace": "$INTERFACE$" }
|
||||
],
|
||||
"rules": [
|
||||
"-A INPUT -i $INTERFACE$ -j ACCEPT",
|
||||
"-A OUTPUT -o $INTERFACE$ -j ACCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ipaddress",
|
||||
"fw-state": true,
|
||||
"ip-version": 4,
|
||||
"comment": "allow access from/to IP",
|
||||
"dependson": [
|
||||
{ "var": "excluded-ips", "type": "list", "replace": "$IPADDRESS$" }
|
||||
],
|
||||
"rules": [
|
||||
"-A INPUT -s $IPADDRESS$ -j ACCEPT",
|
||||
"-A INPUT -d $IPADDRESS$ -j ACCEPT"
|
||||
]
|
||||
}
|
||||
],
|
||||
"restriction_rules": [
|
||||
{
|
||||
"name": "ipaddress",
|
||||
"fw-state": true,
|
||||
"ip-version": 4,
|
||||
"dependson": [
|
||||
{ "var": "restricted-ips", "type": "list", "replace": "$IPADDRESS$" }
|
||||
],
|
||||
"comment": "Block access from IP-address",
|
||||
"rules": [
|
||||
"-A INPUT -s $IPADDRESS$ -j DROP"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
368
includes/firewall.php
Normal file
368
includes/firewall.php
Normal file
|
@ -0,0 +1,368 @@
|
|||
<?php
|
||||
|
||||
require_once 'includes/status_messages.php';
|
||||
require_once 'includes/functions.php';
|
||||
|
||||
define('RASPAP_IPTABLES_SCRIPT', "/tmp/iptables_raspap.sh");
|
||||
define('RASPAP_IP6TABLES_SCRIPT', "/tmp/ip6tables_raspap.sh");
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $rule
|
||||
* @param array $conf
|
||||
* @return array $don
|
||||
*/
|
||||
function getDependson(&$rule, &$conf)
|
||||
{
|
||||
if (isset($rule["dependson"][0]) ) {
|
||||
$don = &$rule["dependson"];
|
||||
if (!empty($don[0]) && isset($conf[$don[0]["var"]]) ) {
|
||||
if (!isset($don[0]["type"]) ) { $don[0]["type"]="bool";
|
||||
}
|
||||
return $don;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $sect
|
||||
* @param array $conf
|
||||
* @return boolean $active
|
||||
*/
|
||||
function isRuleEnabled(&$sect, &$conf)
|
||||
{
|
||||
$fw_on = isset($conf["firewall-enable"]) && $conf["firewall-enable"];
|
||||
$active = isset($sect["fw-state"]) && $sect["fw-state"]==1;
|
||||
$active = $fw_on ? $active : !$active;
|
||||
$active = $active || !isset($sect["fw-state"]);
|
||||
if (($don = getDependson($sect, $conf)) !== false
|
||||
&& $don[0]["type"] == "bool" && !$conf[$don[0]["var"]]
|
||||
) { $active = false;
|
||||
}
|
||||
return $active;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $sect
|
||||
* @param array $conf
|
||||
* @return string $str
|
||||
*/
|
||||
function createRuleStr(&$sect, &$conf)
|
||||
{
|
||||
if (!is_array($sect["rules"]) ) { return "";
|
||||
}
|
||||
$rules = $sect["rules"];
|
||||
$depon = getDependson($sect, $conf);
|
||||
$rs = array();
|
||||
foreach ( $rules as $rule ) {
|
||||
if (preg_match('/\$[a-z0-9]*\$/i', $rule) ) {
|
||||
$r = array($rule);
|
||||
foreach ( $depon as $dep ) {
|
||||
$rr = array();
|
||||
$repl=$val="";
|
||||
switch ( $dep["type"] ) {
|
||||
case "list":
|
||||
if (isset($dep["var"]) && !empty($conf[$dep["var"]]) ) { $val = explode(' ', $conf[$dep["var"]]);
|
||||
}
|
||||
if (!empty($val) && isset($dep["replace"]) ) { $repl=$dep["replace"];
|
||||
}
|
||||
break;
|
||||
case "string":
|
||||
if (isset($dep["var"]) ) { $val=$conf[$dep["var"]];
|
||||
}
|
||||
if (!empty($val) && isset($dep["replace"]) ) { $repl=$dep["replace"];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!empty($repl) && !empty($val) ) {
|
||||
if (is_array($val) ) {
|
||||
foreach ( $val as $v ) { $rr = array_merge($rr, str_replace($repl, $v, $r));
|
||||
}
|
||||
}
|
||||
else { $rr = array_merge($rr, str_replace($repl, $val, $r));
|
||||
}
|
||||
}
|
||||
$r = !empty($rr) ? $rr : $r;
|
||||
}
|
||||
$rs = array_merge($rs, $rr);
|
||||
} else {
|
||||
$rs[] = $rule;
|
||||
}
|
||||
}
|
||||
$str="";
|
||||
foreach ( $rs as $r ) {
|
||||
if (!preg_match('/\$[a-z0-9]*\$/i', $r) ) { $str .= '$IPT '.$r."\n";
|
||||
}
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $rule
|
||||
* @return boolean
|
||||
*/
|
||||
function isIPv4(&$rule)
|
||||
{
|
||||
return !isset($rule["ip-version"]) || strstr($rule["ip-version"], "4") !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $rule
|
||||
* @return boolean
|
||||
*/
|
||||
function isIPv6(&$rule)
|
||||
{
|
||||
return !isset($rule["ip-version"]) || strstr($rule["ip-version"], "6") !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function configureFirewall()
|
||||
{
|
||||
$json = file_get_contents(RASPI_IPTABLES_CONF);
|
||||
$ipt = json_decode($json, true);
|
||||
$conf = ReadFirewallConf();
|
||||
$txt = "#!/bin/bash\n";
|
||||
file_put_contents(RASPAP_IPTABLES_SCRIPT, $txt);
|
||||
file_put_contents(RASPAP_IP6TABLES_SCRIPT, $txt);
|
||||
file_put_contents(RASPAP_IPTABLES_SCRIPT, 'IPT="iptables"'."\n", FILE_APPEND);
|
||||
file_put_contents(RASPAP_IP6TABLES_SCRIPT, 'IPT="ip6tables"'."\n", FILE_APPEND);
|
||||
$txt = "\$IPT -F\n";
|
||||
$txt .= "\$IPT -X\n";
|
||||
$txt .= "\$IPT -t nat -F\n";
|
||||
file_put_contents(RASPAP_IPTABLES_SCRIPT, $txt, FILE_APPEND);
|
||||
file_put_contents(RASPAP_IP6TABLES_SCRIPT, $txt, FILE_APPEND);
|
||||
if (empty($conf) || empty($ipt) ) { return false;
|
||||
}
|
||||
$count=0;
|
||||
foreach ( $ipt["order"] as $idx ) {
|
||||
if (isset($ipt[$idx]) ) {
|
||||
foreach ( $ipt[$idx] as $i => $sect ) {
|
||||
if (isRuleEnabled($sect, $conf) ) {
|
||||
$str_rules= createRuleStr($sect, $conf);
|
||||
if (!empty($str_rules) ) {
|
||||
if (isIPv4($sect) ) { file_put_contents(RASPAP_IPTABLES_SCRIPT, $str_rules, FILE_APPEND);
|
||||
}
|
||||
if (isIPv6($sect) ) { file_put_contents(RASPAP_IP6TABLES_SCRIPT, $str_rules, FILE_APPEND);
|
||||
}
|
||||
++$count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($count > 0 ) {
|
||||
exec("chmod +x ".RASPAP_IPTABLES_SCRIPT);
|
||||
exec("sudo ".RASPAP_IPTABLES_SCRIPT);
|
||||
exec("sudo iptables-save | sudo tee /etc/iptables/rules.v4");
|
||||
unlink(RASPAP_IPTABLES_SCRIPT);
|
||||
exec("chmod +x ".RASPAP_IP6TABLES_SCRIPT);
|
||||
exec("sudo ".RASPAP_IP6TABLES_SCRIPT);
|
||||
exec("sudo ip6tables-save | sudo tee /etc/iptables/rules.v6");
|
||||
unlink(RASPAP_IP6TABLES_SCRIPT);
|
||||
}
|
||||
return ($count > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $conf
|
||||
* @return string $ret
|
||||
*/
|
||||
function WriteFirewallConf($conf)
|
||||
{
|
||||
$ret = false;
|
||||
if (is_array($conf) ) { write_php_ini($conf, RASPI_FIREWALL_CONF);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array $conf
|
||||
*/
|
||||
function ReadFirewallConf()
|
||||
{
|
||||
$conf = array();
|
||||
if (file_exists(RASPI_FIREWALL_CONF) ) {
|
||||
$conf = parse_ini_file(RASPI_FIREWALL_CONF);
|
||||
}
|
||||
if ( !isset($conf["firewall-enable"]) ) {
|
||||
$conf["firewall-enable"] = false;
|
||||
$conf["ssh-enable"] = false;
|
||||
$conf["http-enable"] = false;
|
||||
$conf["excl-devices"] = "";
|
||||
$conf["excluded-ips"] = "";
|
||||
$conf["ap-device"] = "";
|
||||
$conf["client-device"] = "";
|
||||
$conf["restricted-ips"] = "";
|
||||
}
|
||||
exec('ifconfig | grep -E -i "^tun[0-9]"', $ret);
|
||||
$conf["openvpn-enable"] = !empty($ret);
|
||||
unset($ret);
|
||||
exec('ifconfig | grep -E -i "^wg[0-9]"', $ret);
|
||||
$conf["wireguard-enable"] = !empty($ret);
|
||||
return $conf;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string $ips
|
||||
*/
|
||||
function getVPN_IPs()
|
||||
{
|
||||
$ips = "";
|
||||
// get openvpn and wireguard server IPs
|
||||
if (RASPI_OPENVPN_ENABLED && ($fconf = glob(RASPI_OPENVPN_CLIENT_PATH ."/*.conf")) !== false && !empty($fconf) ) {
|
||||
foreach ( $fconf as $f ) {
|
||||
unset($result);
|
||||
exec('cat '.$f.' | sed -rn "s/^remote\s*([a-z0-9\.\-\_:]*)\s*([0-9]*)\s*$/\1 \2/ip" ', $result);
|
||||
if (!empty($result) ) {
|
||||
$result = explode(" ", $result[0]);
|
||||
$ip = (isset($result[0])) ? $result[0] : "";
|
||||
$port = (isset($result[1])) ? $result[1] : "";
|
||||
if (!empty($ip) ) {
|
||||
$ip = gethostbyname($ip);
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP) && strpos($ips, $ip) === false ) { $ips .= " $ip";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// get wireguard server IPs
|
||||
if (RASPI_WIREGUARD_ENABLED && ($fconf = glob(RASPI_WIREGUARD_PATH ."/*.conf")) !== false && !empty($fconf) ) {
|
||||
foreach ( $fconf as $f ) {
|
||||
unset($result);
|
||||
exec('sudo /bin/cat '.$f.' | sed -rn "s/^endpoint\s*=\s*\[?([a-z0-9\.\-\_:]*)\]?:([0-9]*)\s*$/\1 \2/ip" ', $result);
|
||||
if (!empty($result) ) {
|
||||
$result = explode(" ", $result[0]);
|
||||
$ip = (isset($result[0])) ? $result[0] : "";
|
||||
$port = (isset($result[1])) ? $result[1] : "";
|
||||
if (!empty($ip) ) {
|
||||
$ip = gethostbyname($ip);
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP) && strpos($ips, $ip) === false ) { $ips .= " $ip";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return trim($ips);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array $fw_conf
|
||||
*/
|
||||
function getFirewallConfiguration()
|
||||
{
|
||||
$fw_conf = ReadFirewallConf();
|
||||
|
||||
$json = file_get_contents(RASPI_IPTABLES_CONF);
|
||||
getWifiInterface();
|
||||
$ap_device = $_SESSION['ap_interface'];
|
||||
$clients = getClients();
|
||||
$str_clients = "";
|
||||
foreach( $clients["device"] as $dev ) {
|
||||
if (!$dev["isAP"] ) {
|
||||
if (!empty($str_clients) ) { $str_clients .= ", ";
|
||||
}
|
||||
$str_clients .= $dev["name"];
|
||||
}
|
||||
}
|
||||
$fw_conf["ap-device"] = $ap_device;
|
||||
$fw_conf["client-list"] = $str_clients;
|
||||
$id=findCurrentClientIndex($clients);
|
||||
if ($id >= 0 ) { $fw_conf["client-device"] = $clients["device"][$id]["name"];
|
||||
}
|
||||
return $fw_conf;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function updateFirewall()
|
||||
{
|
||||
$fw_conf = getFirewallConfiguration();
|
||||
if ( isset($fw_conf["firewall-enable"]) ) {
|
||||
WriteFirewallConf($fw_conf);
|
||||
configureFirewall();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function DisplayFirewallConfig()
|
||||
{
|
||||
$status = new StatusMessages();
|
||||
|
||||
$fw_conf = getFirewallConfiguration();
|
||||
$ap_device = $fw_conf["ap-device"];
|
||||
$str_clients = $fw_conf["client-list"];
|
||||
|
||||
if (!empty($_POST)) {
|
||||
$fw_conf["ssh-enable"] = isset($_POST['ssh-enable']);
|
||||
$fw_conf["http-enable"] = isset($_POST['http-enable']);
|
||||
$fw_conf["firewall-enable"] = isset($_POST['firewall-enable']) || isset($_POST['apply-firewall']);
|
||||
if (isset($_POST['firewall-enable']) ) { $status->addMessage(_('Firewall is now enabled'), 'success');
|
||||
}
|
||||
if (isset($_POST['apply-firewall']) ) { $status->addMessage(_('Firewall settings changed'), 'success');
|
||||
}
|
||||
if (isset($_POST['firewall-disable']) ) { $status->addMessage(_('Firewall is now disabled'), 'warning');
|
||||
}
|
||||
if (isset($_POST['save-firewall']) ) { $status->addMessage(_('Firewall settings saved. Firewall is still disabled.'), 'success');
|
||||
}
|
||||
if (isset($_POST['excl-devices']) ) {
|
||||
$excl = filter_var($_POST['excl-devices'], FILTER_SANITIZE_STRING);
|
||||
$excl = str_replace(',', ' ', $excl);
|
||||
$excl = trim(preg_replace('/\s+/', ' ', $excl));
|
||||
if ($fw_conf["excl-devices"] != $excl ) {
|
||||
$status->addMessage(_('Exclude devices '. $excl), 'success');
|
||||
$fw_conf["excl-devices"] = $excl;
|
||||
}
|
||||
}
|
||||
if (isset($_POST['excluded-ips']) ) {
|
||||
$excl = filter_var($_POST['excluded-ips'], FILTER_SANITIZE_STRING);
|
||||
$excl = str_replace(',', ' ', $excl);
|
||||
$excl = trim(preg_replace('/\s+/', ' ', $excl));
|
||||
if (!empty($excl) ) {
|
||||
$excl = explode(' ', $excl);
|
||||
$str_excl = "";
|
||||
foreach ( $excl as $ip ) {
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP) ) { $str_excl .= "$ip ";
|
||||
} else { $status->addMessage(_('Exclude IP address '. $ip . ' failed - not a valid IP address'), 'warning');
|
||||
}
|
||||
}
|
||||
}
|
||||
$str_excl = trim($str_excl);
|
||||
if ($fw_conf["excluded-ips"] != $str_excl ) {
|
||||
$status->addMessage(_('Exclude IP address(es) '. $str_excl), 'success');
|
||||
$fw_conf["excluded-ips"] = $str_excl;
|
||||
}
|
||||
}
|
||||
WriteFirewallConf($fw_conf);
|
||||
configureFirewall();
|
||||
}
|
||||
$vpn_ips = getVPN_IPs();
|
||||
echo renderTemplate(
|
||||
"firewall", compact(
|
||||
"status",
|
||||
"ap_device",
|
||||
"str_clients",
|
||||
"fw_conf",
|
||||
"vpn_ips"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
@ -41,6 +41,7 @@ require_once 'includes/system.php';
|
|||
require_once 'includes/sysstats.php';
|
||||
require_once 'includes/configure_client.php';
|
||||
require_once 'includes/networking.php';
|
||||
require_once 'includes/firewall.php';
|
||||
require_once 'includes/themes.php';
|
||||
require_once 'includes/data_usage.php';
|
||||
require_once 'includes/about.php';
|
||||
|
@ -175,6 +176,11 @@ $bridgedEnabled = getBridgedState();
|
|||
<?php if (RASPI_TORPROXY_ENABLED) : ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="torproxy_conf"><i class="fas fa-eye-slash fa-fw mr-2"></i><span class="nav-label"><?php echo _("TOR proxy"); ?></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php if (RASPI_FIREWALL_ENABLED) : ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="firewall_conf"><i class="fas fa-shield-alt fa-fw mr-2"></i><span class="nav-label"><?php echo _("Firewall"); ?></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php if (RASPI_CONFAUTH_ENABLED) : ?>
|
||||
|
@ -274,6 +280,9 @@ $bridgedEnabled = getBridgedState();
|
|||
case "/torproxy_conf":
|
||||
DisplayTorProxyConfig();
|
||||
break;
|
||||
case "/firewall_conf":
|
||||
DisplayFirewallConfig();
|
||||
break;
|
||||
case "/auth_conf":
|
||||
DisplayAuthConfig($config['admin_user'], $config['admin_pass']);
|
||||
break;
|
||||
|
|
20
installers/install_feature_firewall.sh
Normal file
20
installers/install_feature_firewall.sh
Normal file
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# RaspAP feature installation: Firewall
|
||||
# to be sources by the RaspAP installer script
|
||||
# Author: @zbchristian <christian@zeitnitz.eu>
|
||||
# Author URI: https://github.com/zbchristian/
|
||||
# License: GNU General Public License v3.0
|
||||
# License URI: https://github.com/raspap/raspap-webgui/blob/master/LICENSE
|
||||
|
||||
function _install_feature_firewall() {
|
||||
name="feature firewall"
|
||||
|
||||
_install_log "Install $name"
|
||||
# create config dir
|
||||
sudo mkdir "$raspap_network/firewall" || _install_status 1 "Unable to create firewall config directory"
|
||||
# copy firewall configuration
|
||||
sudo cp "$webroot_dir/config/iptables_rules.json" "$raspap_network/firewall/" || _install_status 1 "Unable to copy iptables templates"
|
||||
sudo chown $raspap_user:$raspap_user -R "$raspap_network/firewall" || _install_status 1 "Unable to change ownership of firewall directory and files "
|
||||
_install_status 0
|
||||
}
|
|
@ -62,3 +62,9 @@ www-data ALL=(ALL) NOPASSWD:/bin/cat /etc/wireguard/*.conf
|
|||
www-data ALL=(ALL) NOPASSWD:/bin/cat /etc/wireguard/wg-*.key
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/rm /etc/wireguard/*.conf
|
||||
www-data ALL=(ALL) NOPASSWD:/bin/rm /etc/wireguard/wg-*.key
|
||||
www-data ALL=(ALL) NOPASSWD:/tmp/iptables_raspap.sh
|
||||
www-data ALL=(ALL) NOPASSWD:/tmp/ip6tables_raspap.sh
|
||||
www-data ALL=(ALL) NOPASSWD:/usr/sbin/iptables-save
|
||||
www-data ALL=(ALL) NOPASSWD:/usr/sbin/ip6tables-save
|
||||
www-data ALL=(ALL) NOPASSWD:/usr/bin/tee /etc/iptables/rules.v4
|
||||
www-data ALL=(ALL) NOPASSWD:/usr/bin/tee /etc/iptables/rules.v6
|
||||
|
|
29
installers/update_firewall.sh
Normal file
29
installers/update_firewall.sh
Normal file
|
@ -0,0 +1,29 @@
|
|||
#!/bin/bash
|
||||
# include the raspap helper functions
|
||||
source /usr/local/sbin/raspap_helpers.sh
|
||||
|
||||
_getWebRoot
|
||||
|
||||
echo -n "Update firewall ... "
|
||||
|
||||
cat << EOF > /tmp/updateFirewall.php
|
||||
<?php
|
||||
//set_include_path('/var/www/html/');
|
||||
\$_SESSION['locale']="en_GB.UTF-8";
|
||||
|
||||
require_once 'includes/config.php';
|
||||
require_once 'includes/defaults.php';
|
||||
require_once RASPI_CONFIG.'/raspap.php';
|
||||
require_once 'includes/locale.php';
|
||||
require_once 'includes/wifi_functions.php';
|
||||
require_once 'includes/get_clients.php';
|
||||
require_once 'includes/firewall.php';
|
||||
|
||||
updateFirewall();
|
||||
|
||||
?>
|
||||
EOF
|
||||
|
||||
sudo php -d include_path=$raspap_webroot /tmp/updateFirewall.php
|
||||
rm /tmp/updateFirewall.php
|
||||
echo "done."
|
|
@ -1140,3 +1140,74 @@ msgstr "WireGuard configuration updated successfully"
|
|||
msgid "WireGuard configuration failed to be updated"
|
||||
msgstr "WireGuard configuration failed to be updated"
|
||||
|
||||
#: templates/firewall.php
|
||||
|
||||
msgid "Client Firewall"
|
||||
msgstr "Client Firewall"
|
||||
|
||||
msgid "Firewall is ENABLED"
|
||||
msgstr "Firewall is ENABLED"
|
||||
|
||||
msgid "Firewall is OFF"
|
||||
msgstr "Firewall is OFF"
|
||||
|
||||
msgid "The default firewall will only allow outgoing and already established traffic."
|
||||
msgstr "The default firewall will only allow outgoing and already established traffic."
|
||||
|
||||
msgid "No incoming UDP traffic is allowed."
|
||||
msgstr "No incoming UDP traffic is allowed."
|
||||
|
||||
msgid "There are no restrictions for the access point <code>%s</code>."
|
||||
msgstr "There are no restrictions for the access point <code>%s</code>."
|
||||
|
||||
msgid "Exception: Service"
|
||||
msgstr "Exception: Service"
|
||||
|
||||
msgid "allow SSH access on port 22"
|
||||
msgstr "allow SSH access on port 22"
|
||||
|
||||
msgid "allow access to the RaspAP GUI on port 80 or 443"
|
||||
msgstr "allow access to the RaspAP GUI on port 80 or 443"
|
||||
|
||||
msgid "Allow incoming connections for some services from the internet side."
|
||||
msgstr "Allow incoming connections for some services from the internet side."
|
||||
|
||||
msgid "Exception: network device"
|
||||
msgstr "Exception: network device"
|
||||
|
||||
msgid "Exclude device(s)"
|
||||
msgstr "Exclude device(s)"
|
||||
|
||||
msgid "Exclude the given network device(s) (separated by a blank or comma) from firewall rules."
|
||||
msgstr "Exclude the given network device(s) (separated by a blank or comma) from firewall rules."
|
||||
|
||||
msgid "Current client devices: <code>%s</code>"
|
||||
msgstr "Current client devices: <code>%s</code>"
|
||||
|
||||
msgid "The access point <code>%s</code> is per default excluded."
|
||||
msgstr "The access point <code>%s</code> is per default excluded."
|
||||
|
||||
msgid "Exception: IP-Address"
|
||||
msgstr "Exception: IP-Address"
|
||||
|
||||
msgid "Allow incoming connections from"
|
||||
msgstr "Allow incoming connections from"
|
||||
|
||||
msgid "For the given IP-addresses (separated by a blank or comma) the incoming connection (via TCP and UDP) is accepted."
|
||||
msgstr "For the given IP-addresses (separated by a blank or comma) the incoming connection (via TCP and UDP) is accepted."
|
||||
|
||||
msgid "This is required for an OpenVPN via UDP or Wireguard connection."
|
||||
msgstr "This is required for an OpenVPN via UDP or Wireguard connection."
|
||||
|
||||
msgid "The list of configured VPN server IP addresses: <code><b>%s</b></code>"
|
||||
msgstr "The list of configured VPN server IP addresses: <code><b>%s</b></code>"
|
||||
|
||||
msgid "Disable Firewall"
|
||||
msgstr "Disable Firewall"
|
||||
|
||||
msgid "Enable Firewall"
|
||||
msgstr "Enable Firewall"
|
||||
|
||||
msgid "Apply changes"
|
||||
msgstr "Apply changes"
|
||||
:
|
||||
|
|
110
templates/firewall.php
Executable file
110
templates/firewall.php
Executable file
|
@ -0,0 +1,110 @@
|
|||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<i class="fas fa-shield-alt mr-2"></i><?php echo _("Firewall"); ?>
|
||||
</div>
|
||||
</div><!-- /.row -->
|
||||
</div><!-- /.card-header -->
|
||||
<div class="card-body">
|
||||
<?php $status->showMessages(); ?>
|
||||
<h4><?php echo _("Client Firewall"); ?></h4>
|
||||
<?php if ( $fw_conf["firewall-enable"]) : ?>
|
||||
<i class="fas fa-circle mr-2 service-status-up"></i><?php echo _("Firewall is ENABLED"); ?>
|
||||
<?php else : ?>
|
||||
<i class="fas fa-circle mr-2 service-status-down"></i><?php echo _("Firewall is OFF"); ?>
|
||||
<?php endif ?>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<p class="mr-2">
|
||||
<small>
|
||||
<?php echo _("The default firewall will only allow outgoing and already established traffic."); ?><br />
|
||||
<?php echo _("No incoming UDP traffic is allowed."); ?><br />
|
||||
<?php printf(_("There are no restrictions for the access point <code>%s</code>."), $ap_device); ?>
|
||||
</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<form id="frm-firewall" action="firewall_conf" method="POST" >
|
||||
<?php echo CSRFTokenFieldTag(); ?>
|
||||
<h5><?php echo _("Exception: Service"); ?></h4>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<div class="custom-control custom-switch">
|
||||
<input class="custom-control-input" id="ssh-enable" type="checkbox" name="ssh-enable" value="1" aria-describedby="exception-description" <?php if ($fw_conf["ssh-enable"]) echo "checked"; ?> >
|
||||
<label class="custom-control-label" for="ssh-enable"><?php echo _("allow SSH access on port 22") ?></label>
|
||||
</div>
|
||||
<div class="custom-control custom-switch">
|
||||
<input class="custom-control-input" id="http-enable" type="checkbox" name="http-enable" value="1" aria-describedby="exceptions-description" <?php if ($fw_conf["http-enable"]) echo "checked"; ?> >
|
||||
<label class="custom-control-label" for="http-enable"><?php echo _("allow access to the RaspAP GUI on port 80 or 443") ?></label>
|
||||
</div>
|
||||
<p class="mb-0" id="exceptions-description">
|
||||
<small><?php echo _("Allow incoming connections for some services from the internet side.") ?></small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<h5><?php echo _("Exception: network device"); ?></h4>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<label for="excl-device"><?php echo _("Exclude device(s)") ?></label>
|
||||
<input class="form-control" id="excl-devices" type="text" name="excl-devices" value="<?php echo $fw_conf["excl-devices"] ?>" aria-describedby="exclusion-description" >
|
||||
<p class="mb-0" id="exclusion-description">
|
||||
<small>
|
||||
<?php echo _("Exclude the given network device(s) (separated by a blank or comma) from firewall rules."); ?><br />
|
||||
<?php printf(_("Current client devices: <code>%s</code>"), $str_clients); ?><br />
|
||||
<?php printf(_("The access point <code>%s</code> is per default excluded."), $ap_device); ?>
|
||||
</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<h5><?php echo _("Exception: IP-Address"); ?></h4>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<label for="excluded-ips"><?php echo _("Allow incoming connections from") ?></label>
|
||||
<input class="form-control" id="excluded-ips" type="text" name="excluded-ips" value="<?php echo $fw_conf["excluded-ips"] ?>" aria-describedby="excl-ips-description" >
|
||||
<p class="mb-0" id="excl-ips-description">
|
||||
<small>
|
||||
<?php echo _("For the given IP-addresses (separated by a blank or comma) the incoming connection (via TCP and UDP) is accepted."); ?><br />
|
||||
<?php echo _("This is required for an OpenVPN via UDP or Wireguard connection."); ?><br />
|
||||
<?php if ( !empty($vpn_ips) ) printf (_("The list of configured VPN server IP addresses: <code><b>%s</b></code>"), $vpn_ips); ?>
|
||||
</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($fw_conf["firewall-enable"]) : ?>
|
||||
<input type="submit" class="btn btn-outline btn-primary" value="<?php echo _("Apply changes"); ?>" name="apply-firewall" />
|
||||
<input type="submit" class="btn btn-warning firewall-apply" value="<?php echo _("Disable Firewall") ?>" name="firewall-disable" data-toggle="modal" data-target="#firewallModal"/>
|
||||
<?php else : ?>
|
||||
<input type="submit" class="btn btn-outline btn-primary" value="<?php echo _("Save settings"); ?>" name="save-firewall" />
|
||||
<input type="submit" class="btn btn-success firewall-apply" value="<?php echo _("Enable Firewall") ?>" name="firewall-enable" data-toggle="modal" data-target="#firewallModal"/>
|
||||
<?php endif ?>
|
||||
</form>
|
||||
</div><!-- /.card-body -->
|
||||
<div class="card-footer"></div>
|
||||
</div><!-- /.card -->
|
||||
</div><!-- /.col-lg-12 -->
|
||||
</div><!-- /.row -->
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="firewallModal" tabindex="-1" role="dialog" aria-labelledby="ModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<div class="modal-title" id="ModalLabel">
|
||||
<i class="fas fa-sync-alt mr-2"></i><?php echo _("Executing firewall option") ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="col-md-12 mb-3 mt-1">
|
||||
<?php if($fw_conf["firewall-enable"]) echo _("Disabling firewall").'...'; else echo _("Enabling firewall").'...'; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline btn-primary" data-dismiss="modal"><?php echo _("Close"); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
0
templates/torproxy.php
Normal file → Executable file
0
templates/torproxy.php
Normal file → Executable file
0
templates/wireguard.php
Normal file → Executable file
0
templates/wireguard.php
Normal file → Executable file
Loading…
Reference in a new issue