Tous les détails techniques suite à un rapide survol du firmware :
Le script
/etc/init.d/mapt qui s'occupe de la configuration :
#!/bin/sh /etc/rc.common
service=mapt
logger -t "${service}[$$]" "$action"
[...]
start() {
local control="/proc/net/nat46/control"
local ifname="$(status get net_mapt_ifname)"
local ifnamev6="$(status get net_ipv6_ifname)"
local localv4="$(status get net_mapt_bmr_prefixv4)/$(status get net_mapt_bmr_maskv4)"
local localv6="$(status get net_ipv6_prefix)"
local remotev6="$(status get net_mapt_dmr_prefixv6)/$(status get net_mapt_dmr_maskv6)"
local ealen="$(status get net_mapt_ealen)"
local offset="$(status get net_mapt_offset)"
local ip6addr="$(status get net_mapt_ip6addr)"
local ipaddr="$(status get net_mapt_ipaddr)"
local ipmask="$(status get net_mapt_bmr_maskv4)"
local portsets="$(status get net_mapt_portsets)"
local mapt_subnet="$(status get net_ipv6_prefix | sed s:/56:/64:)"
echo add ${ifname} > ${control}
echo config ${ifname} local.style MAP local.v4 ${localv4} \
local.v6 ${localv6} local.ea-len ${ealen} \
local.psid-offset ${offset} remote.v4 0.0.0.0/0 \
remote.v6 ${remotev6} remote.style RFC6052 \
remote.ea-len 0 remote.psid-offset 0 > ${control}
ip -6 address add ${ip6addr} dev ${ifname}
ip address add ${ipaddr}/${ipmask} dev ${ifname}
ip route delete local ${ip6addr} via :: dev lo
echo ${portsets} | sed "s/-/ /g" > /proc/sys/net/ipv4/port_ranges
# only one range is required for icmp
local range=$(echo ${portsets} | sed "s/ .*//")
# ipv4 SNAT
iptables -t nat -F POSTROUTING
iptables -t nat -A POSTROUTING -p icmp -o ${ifname} \
-j SNAT --to-source ${ipaddr}:${range}
iptables -t nat -A POSTROUTING -p tcp -o ${ifname} \
-j SNAT --to-source ${ipaddr} --random
iptables -t nat -A POSTROUTING -p udp -o ${ifname} \
-j SNAT --to-source ${ipaddr} --random
# user nat
iptables -t nat -F PREROUTING
iptables -t nat -A PREROUTING -d ${ipaddr} -j USER_NAT
iptables -t nat -A PREROUTING -d ${ipaddr} -j MINIUPNPD
/etc/init.d/nat user_nat
xtables -F MAPT_FILTER
xtables -D FORWARD -j MAPT_FILTER
xtables -A FORWARD -j MAPT_FILTER
# ipv6 forward
ip6tables -A MAPT_FILTER -i ${ifname} -s ${mapt_subnet} \
-o ${ifnamev6} -d ${remotev6} -j ACCEPT
ip6tables -A MAPT_FILTER -o ${ifname} -d ${mapt_subnet} \
-i ${ifnamev6} -s ${remotev6} -j ACCEPT
# ipv4 forward
iptables -A MAPT_FILTER -o ${ifname} -m state --state INVALID -j DROP
iptables -A MAPT_FILTER -i ${ifname} -m state --state NEW -j WIN_FILTER
iptables -A MAPT_FILTER -o ${ifname} -m state --state NEW -j WIN_FILTER
iptables -A MAPT_FILTER -o ${ifname} -p tcp -m tcp --dport 25 -j SMTP_FILTER
# use mapt0 as default ipv4 route
ifconfig ${ifname} up
ip route delete default
ip route add default dev ${ifname}
ip route delete default table lan_t
ip route add default dev ${ifname} table lan_t
# update status
status set net_mapt_status up
/etc/init.d/nat algs
diaglog event mapt
event notify mapt-up
}
stop() {
local control="/proc/net/nat46/control"
local ifname="$(status get net_mapt_ifname)"
# cleanup firewall
iptables -t nat -F POSTROUTING
iptables -t nat -F PREROUTING
xtables -F MAPT_FILTER
xtables -D FORWARD -j MAPT_FILTER
# clean up mapt iface
ifconfig ${ifname} down
echo del ${ifname} > ${control}
# update status
status set net_mapt_status down
/etc/init.d/nat algs
event notify mapt-down
}
Les diverses variables présentes au début du script sont poussées par le système de configuration maison (HTTP/XML récupéré périodiquement) de SFR.
Le module standard d'OpenWRT pour faire la partie translation d'adresses de MAP-T, appelé
NAT46, est utilisé. Netfilter s'occupe de randomiser proprement les ports des connexions sortantes.
L'interface web a bien été adaptée pour restreindre la redirection de ports aux ports autorisés, avec des messages de type : "Cette plage de ports est indisponible en IP".
Pour les plus curieux, l'image est à télécharger ici
http://ncdn.nb4dsl.neufbox.neuf.fr/nb6_Version 3.5.1/NB6-MAIN-R3.5.1 (à extraire avec binwalk).