-
-
Save anonymous/0fdec75fa20a7f1ce4806391d6b0429b to your computer and use it in GitHub Desktop.
## /etc/firewall.user | |
# This file is interpreted as shell script. | |
# Put your custom iptables rules here, they will | |
# be executed with each firewall (re-)start. | |
# Internal uci firewall chains are flushed and recreated on reload, so | |
# put custom rules into the root chains e.g. INPUT or FORWARD or into the | |
# special user chains, e.g. input_wan_rule or postrouting_lan_rule. | |
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 0 -j MARK --set-mark 10 | |
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 1 -j MARK --set-mark 11 | |
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 2 -j MARK --set-mark 12 | |
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 3 -j MARK --set-mark 13 | |
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 4 -j MARK --set-mark 14 | |
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 5 -j MARK --set-mark 15 | |
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 6 -j MARK --set-mark 16 | |
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 7 -j MARK --set-mark 17 | |
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 8 -j MARK --set-mark 18 | |
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 9 -j MARK --set-mark 19 | |
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 10 -j MARK --set-mark 20 | |
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 11 -j MARK --set-mark 21 | |
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 12 -j MARK --set-mark 22 | |
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 13 -j MARK --set-mark 23 | |
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 14 -j MARK --set-mark 24 | |
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 0 -j MARK --set-mark 10 | |
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 1 -j MARK --set-mark 11 | |
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 2 -j MARK --set-mark 12 | |
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 3 -j MARK --set-mark 13 | |
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 4 -j MARK --set-mark 14 | |
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 5 -j MARK --set-mark 15 | |
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 6 -j MARK --set-mark 16 | |
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 7 -j MARK --set-mark 17 | |
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 8 -j MARK --set-mark 18 | |
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 9 -j MARK --set-mark 19 | |
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 10 -j MARK --set-mark 20 | |
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 11 -j MARK --set-mark 21 | |
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 12 -j MARK --set-mark 22 | |
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 13 -j MARK --set-mark 23 | |
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 14 -j MARK --set-mark 24 |
#$ diff -c /lib/netifd/proto/map.sh.orig /lib/netifd/proto/map.sh | |
*** /lib/netifd/proto/map.sh.orig 2017-05-30 02:45:19.000000000 +0900 | |
--- /lib/netifd/proto/map.sh 2017-05-30 02:45:18.000000000 +0900 | |
*************** | |
*** 135,140 **** | |
--- 135,141 ---- | |
json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR") | |
json_close_object | |
else | |
+ local mark=10 | |
for portset in $(eval "echo \$RULE_${k}_PORTSETS"); do | |
for proto in icmp tcp udp; do | |
json_add_object "" | |
*************** | |
*** 142,152 **** | |
--- 143,155 ---- | |
json_add_string target SNAT | |
json_add_string family inet | |
json_add_string proto "$proto" | |
+ json_add_string mark "$mark" | |
json_add_boolean connlimit_ports 1 | |
json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR") | |
json_add_string snat_port "$portset" | |
json_close_object | |
done | |
+ mark=`expr $mark + 1` | |
done | |
fi | |
if [ "$type" = "map-t" ]; then | |
うちのopenWRT 21.02.0-RC環境で試したところ、範囲外のポートを指定するiptablesを出力していたので、こんな↓感じで設定しました。
https://gist.github.com/osakanataro/a9ba5ded340070b8e6abc28969d7ae4f
Luciに大分、変更が入り細かく設定できるようになりました。
合わせて上記を再チェックしました。やはり--connlimit-mask 32ではconnlimitが効かないようで1番目しか使われませんでした。
以下のようにスクリプトを書き換えました。
ニチバンも今のところ快調です。
connlimit-maskの設定がLuciからできるようになれば良いのですが。
map.shからconnlimit-maskをいじる方法です。
fw3のsnat周りのソースコードをみていたらextraオプションが使えることがわかりました。
extraはユーザー指定の文字列をコマンドとしてスルーするようです。
root@OpenWrt:/lib/netifd/proto# diff -c map.sh.org map.sh
*** map.sh.org Thu Jul 15 18:08:22 2021
--- map.sh Thu Jul 15 17:15:45 2021
***************
*** 150,155 ****
--- 150,156 ----
json_add_boolean connlimit_ports 1
json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
json_add_string snat_port "$portset"
+ json_add_string extra " --connlimit-mask 0 "
json_close_object
done
done
ただ、実際設定してみるとバランスはされるのですが、DNS(UDP)とping(ICMP)は動作するようですが、HTTP/HTTPSまわり(多分TCP)がうまく動作しないです
じゃあ、statisticで分散してみればいいじゃないかと、実行してみると、接続できないことはないのですが、やけに動作が不安定だったりします。
うまく行かないもんですな…というお話だけ。おいておきます
root@OpenWrt:/lib/netifd/proto# diff -c map.sh.org map.sh
*** map.sh.org Thu Jul 15 18:08:22 2021
--- map.sh Thu Jul 15 19:43:45 2021
***************
*** 140,145 ****
--- 140,146 ----
json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
json_close_object
else
+ local packetnum=0
for portset in $(eval "echo \$RULE_${k}_PORTSETS"); do
for proto in icmp tcp udp; do
json_add_object ""
***************
*** 147,157 ****
json_add_string target SNAT
json_add_string family inet
json_add_string proto "$proto"
! json_add_boolean connlimit_ports 1
json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
json_add_string snat_port "$portset"
json_close_object
done
done
fi
if [ "$maptype" = "map-t" ]; then
--- 148,160 ----
json_add_string target SNAT
json_add_string family inet
json_add_string proto "$proto"
! # json_add_boolean connlimit_ports 1
json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
json_add_string snat_port "$portset"
+ json_add_string extra " -m statistic --mode nth --every 15 --packet ${packetnum} "
json_close_object
done
+ packetnum=`expr $packetnum + 1`
done
fi
if [ "$maptype" = "map-t" ]; then
@pantan-cymk さんの見つけた json_add_string extra に刺激を受けて標準のmap.sh への改造だけで
icmp,udp の --connlimit-mask 0 化 と tcp の statistic 化ができましたので参考まで。
パラメータがちゃんと指定されていればポートセットの数の違うサービスでも動的に対応できます。
https://gist.github.com/kurobee-dev/4107b18683e01d17a9b8678e770d272c
--connlimit-mask 32 の時に一番上のセットしか使われていないというのは、数分から数時間程度では使われないので当然なのですが、数日単位で放置してたら他のポートセットもカウントアップされてる事が分かるかと思います。いわゆるYAMAHAのポートセービングNATですね。JPNEみたいな240しか使えないサービスでポート使用量節約のためにそういう設定になっているのですから、ポンポン次のセットに移られても困ります。とはいえ、TCPではなぜか調子が悪いのでそれだけ statistic にしたかったのも事実。
コメントアウトしながらニチバンベンチ回してみました。