Last active
July 18, 2018 16:50
-
-
Save simontraill/bf34665372515cd4699fac7f4ec7e2ba to your computer and use it in GitHub Desktop.
SwiftStack Firewall rules addition - example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Allow extra connections to a SwiftStack controller or node through the firewall. | |
# We require firewall-cmd be installed for this, or else we warn the user. | |
# On startup this script adds a new input chain called localrules-in... | |
# | |
# - To the INPUT chain if on a node; | |
# - To the IN_public_allow chain if on a controller. | |
# | |
# For Enterprise Linux 7 only; for IPv4 only. | |
# | |
# straill@swiftstack.com 2018/07/18 | |
# | |
# To use: | |
# | |
# 1. Copy this script to /opt/swiftstack-extra-firewall-rules/firewall_up.sh | |
# on the controller or every node for which you need extra rules; | |
# 2. Edit the PORTS variable just below the top and set it to the ports you need, in | |
# format <port_number>:<protocol>, whitespace seperated (the example below | |
# allows inbound TCP connections to ports 3000 and 3001, for instance). | |
# 3. Run this script as root with the "add-service" option to add a systemd service | |
# that adds firewall chains on startup: | |
# | |
# # sh /opt/swiftstack-extra-firewall-rules/firewall_up.sh add-service | |
# | |
# 4. As root, set permissions and start the service as shown below. | |
# | |
# # chown -R root:root /opt/swiftstack-extra-firewall-rules | |
# # systemctl start swiftstack-extra-firewall-rules.service | |
# # systemctl status swiftstack-extra-firewall-rules.service | |
# Configure the ports you'd like here. Protocol should be lowercase and one of "tcp", "udp". | |
PORTS="3000:tcp 3001:tcp" | |
fatal() { | |
echo $1 1>&2 | |
exit 1 | |
} | |
# Install a systemd service if requested | |
if [ "$1" = "add-service" ]; then | |
cat <<'EOF' > /lib/systemd/system/swiftstack-extra-firewall-rules.service | |
[Unit] | |
Description=Local firewall rules for SwiftStack nodes | |
Requires=firewalld.service | |
Before=network.target | |
Before=libvirtd.service | |
Before=NetworkManager.service | |
After=firewalld.service | |
After=ssnode-firewall.service | |
[Service] | |
Type=oneshot | |
ExecStart=/usr/bin/bash -c '/opt/swiftstack-extra-firewall-rules/firewall_up.sh' | |
StandardOutput=journal | |
StandardError=journal | |
[Install] | |
WantedBy=multi-user.target | |
EOF | |
echo " >> Added systemd service (swiftstack-extra-firewall-rules.service)" | |
systemctl daemon-reload || fatal "Coudn't run 'systemctl daemon-reload'" | |
systemctl enable swiftstack-extra-firewall-rules.service || fatal "Coudn't run 'systemctl enable swiftstack-extra-firewall-rules.service'" | |
echo " >> Enabled systemd service (swiftstack-extra-firewall-rules.service)" | |
echo | |
echo "Run 'systemctl start swiftstack-extra-firewall-rules.service' to add your firewall rules when ready." | |
exit 0 | |
fi | |
# Otherwise modify the firewall. | |
# We add a new chain named "localrules-in" for the PORTS specified above. | |
# On nodes, we just add this chain to the first free slot in the INPUT chain. | |
# On controllers, we add this chain to the slot in the IN_public_allow chain. | |
CHAIN=INPUT | |
IS_CONTROLLER=false | |
if [ -f /opt/ss/etc/ssman.crt ]; then | |
IS_CONTROLLER=true | |
CHAIN=IN_public_allow | |
fi | |
if [ -f /bin/firewall-cmd -a "$(/bin/firewall-cmd --state)" = "running" ]; then | |
LOCALRULES_SLOT=$( iptables --list ${CHAIN} -n --line-numbers | awk '$2=="localrules-in" {print $1}' | head -1 ) | |
if [ "X${LOCALRULES_SLOT}" != "X" ]; then | |
/bin/firewall-cmd --direct --remove-rule ipv4 filter ${CHAIN} ${LOCALRULES_SLOT} -j localrules-in >/dev/null 2>&1 | |
fi | |
# Remove rules from localrules chain | |
/bin/firewall-cmd --direct --remove-rules ipv4 filter localrules-in >/dev/null 2>&1 | |
# Remove localrules chain | |
/bin/firewall-cmd --direct --remove-chain ipv4 filter localrules-in >/dev/null 2>&1 | |
# Locate the first free slot in the input chain | |
LOCALRULES_SLOT=$( iptables --list ${CHAIN} -n --line-numbers | awk '$2=="localrules-in" {print $1}' | head -1 ) | |
if [ ${IS_CONTROLLER} == 'true' ]; then | |
SLOT=$( iptables --list ${CHAIN} -n --line-numbers | grep ACCEPT | awk '$2=="ACCEPT" {print $1}' | tail -1 ) | |
SLOT=$(( ${SLOT} + 1 )) | |
else | |
SLOT=$( iptables --list ${CHAIN} -n --line-numbers | grep ACCEPT | awk '$2=="ACCEPT" {print $1}' | head -1 ) | |
fi | |
if [ "X${SLOT}" != "X" ]; then | |
if [ "X${LOCALRULES_SLOT}" = "X" ]; then | |
# Add chain | |
/bin/firewall-cmd --direct --add-passthrough ipv4 -N localrules-in >/dev/null 2>&1 | |
# Add chain to input chain | |
/bin/firewall-cmd --direct --add-passthrough ipv4 -I ${CHAIN} ${SLOT} -j localrules-in >/dev/null 2>&1 | |
# Add our ports to the localrules chain. | |
for PORT in $PORTS; do | |
PORTNUM=$( echo ${PORT} | awk -F: '{print $1}' ) | |
PROTO=$( echo ${PORT} | awk -F: '{print $2}' ) | |
/bin/firewall-cmd --direct --add-passthrough ipv4 -A localrules-in -p ${PROTO} --dport ${PORTNUM} -j ACCEPT >/dev/null 2>&1 | |
done | |
else | |
echo "Could not find a free slot in iptables for localrules-in chain - you'll need to allow firewall access to port 3000 manually" | |
fi | |
fi | |
elif [ -f /bin/firewall-cmd ]; then | |
echo "Firewalld is installed but not running. Will not add firewall rules for LOCALRULES". | |
else | |
echo "Firewalld is not installed. If you use iptables, you should add firewall rules for LOCALRULES manually (ie, allow TCP 3000 inbound)." | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment