Skip to content
Snippets Groups Projects
Commit 5e8043ee authored by Bruno STEVANT's avatar Bruno STEVANT
Browse files

Working alpha version, interact with nf through ip6tables sub-process

parent 5016c19c
No related branches found
No related tags found
No related merge requests found
all: nat66-docker
nat66-docker: docker.go ip6tables.go main.go
go build -o nat66-docker
\ No newline at end of file
package main
import (
"fmt"
"github.com/fsouza/go-dockerclient"
)
func main() {
// bindings store network settings for each known container
var bindings map[string]*docker.NetworkSettings
// clear bindings by deleting corresponding port forwarding
func clear_bindings() {
for id, net := range bindings {
ipv6addr := net.GlobalIPv6Address
for port, binds := range net.Ports {
for b := range binds {
del_nat66_portfwd(*dev, port.Proto(), binds[b].HostPort, ipv6addr, port.Port())
}
}
delete(bindings, id)
}
}
func init_docker() {
endpoint := "unix:///var/run/docker.sock"
bindings := make(map[string]*docker.NetworkSettings)
// Init client to Docker socket
client, _ := docker.NewClient(endpoint)
imgs, _ := client.ListImages(docker.ListImagesOptions{All: false})
for _, img := range imgs {
fmt.Println("ID: ", img.ID)
fmt.Println("RepoTags: ", img.RepoTags)
fmt.Println("Created: ", img.Created)
fmt.Println("Size: ", img.Size)
fmt.Println("VirtualSize: ", img.VirtualSize)
fmt.Println("ParentId: ", img.ParentID)
events := make(chan *docker.APIEvents)
client.AddEventListener(events)
// Iterate over docker event
for msg := range events {
// When a container start ...
if msg.Action == "start" {
c, err := client.InspectContainer(msg.ID)
if err == nil {
net := c.NetworkSettings
bindings[msg.ID] = net
ipv6addr := net.GlobalIPv6Address
for port, binds := range net.Ports {
for b := range binds {
add_nat66_portfwd(*dev, port.Proto(), binds[b].HostPort, ipv6addr, port.Port())
}
}
}
}
// When a container die
if msg.Action == "die" {
_, err := client.InspectContainer(msg.ID)
if err == nil {
if net, ok := bindings[msg.ID]; ok {
ipv6addr := net.GlobalIPv6Address
for port, binds := range net.Ports {
for b := range binds {
del_nat66_portfwd(*dev, port.Proto(), binds[b].HostPort, ipv6addr, port.Port())
}
}
delete(bindings, msg.ID)
}
}
}
}
unset_nat66_postrouting(*dev, *prefix)
}
package main
import (
"log"
"os/exec"
"strings"
)
func set_nat66_postrouting(dev, prefix string) {
cmd := new(exec.Cmd)
cmd.Path = "/sbin/ip6tables"
cmd.Args = []string{
"/sbin/ip6tables", "-t", "nat", "-A", "POSTROUTING",
"-o", dev, "-s", prefix,
"-j", "MASQUERADE",
}
log.Println("NAT66 set postrouting: " + strings.Join(cmd.Args, " "))
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
}
func unset_nat66_postrouting(dev, prefix string) {
cmd := new(exec.Cmd)
cmd.Path = "/sbin/ip6tables"
cmd.Args = []string{
"/sbin/ip6tables", "-t", "nat", "-D", "POSTROUTING",
"-o", dev, "-s", prefix,
"-j", "MASQUERADE",
}
log.Println("NAT66 unset postrouting: " + strings.Join(cmd.Args, " "))
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
}
func add_nat66_portfwd(dev, proto, dport, target_ipv6, target_port string) {
cmd := new(exec.Cmd)
cmd.Path = "/sbin/ip6tables"
cmd.Args = []string{
"/sbin/ip6tables", "-t", "nat", "-A", "PREROUTING",
"-i", dev, "-p", proto, "--dport", dport,
"-j", "DNAT",
"--to-destination", "[" + target_ipv6 + "]:" + target_port,
}
log.Println("NAT66 add portfwd: " + strings.Join(cmd.Args, " "))
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
}
func del_nat66_portfwd(dev, proto, dport, target_ipv6, target_port string) {
cmd := new(exec.Cmd)
cmd.Path = "/sbin/ip6tables"
cmd.Args = []string{
"/sbin/ip6tables", "-t", "nat", "-D", "PREROUTING",
"-i", dev, "-p", proto, "--dport", dport,
"-j", "DNAT",
"--to-destination", "[" + target_ipv6 + "]:" + target_port,
}
log.Println("NAT66 del portfwd: " + strings.Join(cmd.Args, " "))
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
}
main.go 0 → 100644
package main
import (
"flag"
"log"
"os"
"os/signal"
)
var dev = flag.String("dev", "", "Egress network device")
var prefix = flag.String("prefix", "", "Internal IPv6 prefix")
func main() {
flag.Parse()
if flag.NArg() != 0 {
log.Fatal("Bad number of argument: %d, expected 0", flag.NArg())
os.Exit(2)
}
if *dev == "" && *prefix == "" {
log.Fatal("Flag -dev and -prefix are mandatory")
os.Exit(2)
}
// Set initial NAT rule
set_nat66_postrouting(*dev, *prefix)
// Clear when signal received
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
go func() {
for range c {
unset_nat66_postrouting(*dev, *prefix)
clear_bindings()
}
}()
// Start docker
init_docker()
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment