mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-23 19:05:37 +00:00
Add primitive iptables wrapper which can set up port forwards
Signed-off-by: David Scott <dave.scott@docker.com>
This commit is contained in:
parent
0c471bdc09
commit
80b234dd3e
1
alpine/packages/iptables/.gitignore
vendored
Normal file
1
alpine/packages/iptables/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
iptables
|
@ -1,5 +1,7 @@
|
||||
FROM ocaml/opam:alpine
|
||||
RUN sudo apk add m4
|
||||
RUN opam install ocamlfind astring -y
|
||||
WORKDIR /app
|
||||
ADD . /app
|
||||
RUN sudo chown -R opam /app
|
||||
RUN ocamlopt -o iptables main.ml
|
||||
RUN opam config exec -- ocamlfind ocamlopt -package unix,astring -linkpkg -o iptables main.ml
|
||||
|
@ -1,2 +1,82 @@
|
||||
let () =
|
||||
print_string "Hello world!\n";;
|
||||
(* ocamlfind ocamlopt -package unix,astring -linkpkg -o iptables iptables.ml *)
|
||||
|
||||
(*
|
||||
--wait -t nat -I DOCKER-INGRESS -p tcp --dport 80 -j DNAT --to-destination 172.18.0.2:80
|
||||
--wait -t nat -D DOCKER-INGRESS -p tcp --dport 80 -j DNAT --to-destination 172.18.0.2:80
|
||||
*)
|
||||
|
||||
let _iptables = "/sbin/iptables"
|
||||
let _proxy = "/usr/bin/docker-proxy"
|
||||
let _pid_dir = "/var/run/service-port-opener"
|
||||
|
||||
type port = {
|
||||
proto: string;
|
||||
dport: string; (* host port *)
|
||||
ip: string; (* container ip *)
|
||||
port: string; (* container port *)
|
||||
}
|
||||
|
||||
let log_fd = Unix.openfile "/var/run/log/service-port-opener.log" [ Unix.O_WRONLY; Unix.O_APPEND; Unix.O_CREAT ] 0o0644
|
||||
|
||||
let logf fmt =
|
||||
Printf.ksprintf (fun s ->
|
||||
let s = s ^ "\n" in
|
||||
let rec loop ofs remaining =
|
||||
if remaining > 0 then begin
|
||||
let n = Unix.write log_fd s ofs remaining in
|
||||
loop (ofs + n) (remaining - n)
|
||||
end in
|
||||
loop 0 (String.length s)
|
||||
) fmt
|
||||
|
||||
let pid_filename { proto; dport; ip; port } =
|
||||
Printf.sprintf "%s/%s.%s.%s.%s.pid" _pid_dir proto dport ip port
|
||||
|
||||
let insert ({ proto; dport; ip; port } as p) =
|
||||
let filename = pid_filename p in
|
||||
logf "insert: creating a proxy for %s" filename;
|
||||
let args = [ _proxy; "-proto"; proto; "-container-ip"; ip; "-container-port"; port; "-host-ip"; "0.0.0.0"; "-host-port"; dport; "-i" ] in
|
||||
let pid = Unix.fork () in
|
||||
if pid != 0 then begin
|
||||
(* write pid to a file (not atomically) *)
|
||||
let oc = open_out filename in
|
||||
output_string oc (string_of_int pid);
|
||||
close_out oc;
|
||||
logf "binary = %s args = %s" _proxy (String.concat "; " args);
|
||||
(try Unix.execv _proxy (Array.of_list args) with e -> logf "Failed with %s" (Printexc.to_string e));
|
||||
exit 1
|
||||
end
|
||||
|
||||
let delete ({ proto; dport; ip; port } as p) =
|
||||
let filename = pid_filename p in
|
||||
logf "delete: removing a proxy for %s" filename;
|
||||
(* read the pid from a file *)
|
||||
try
|
||||
let ic = open_in filename in
|
||||
let pid = int_of_string (input_line ic) in
|
||||
logf "Sending SIGTERM to %d" pid;
|
||||
Unix.kill Sys.sigterm pid
|
||||
with e ->
|
||||
logf "delete: failed to remove proxy for %s: %s" filename (Printexc.to_string e);
|
||||
raise e
|
||||
|
||||
let parse_ip_port ip_port = match Astring.String.cut ~sep:":" ip_port with
|
||||
| None ->
|
||||
failwith ("Failed to parse <ip:port>:" ^ ip_port)
|
||||
| Some (ip, port) ->
|
||||
ip, port
|
||||
|
||||
let _ =
|
||||
( try Unix.mkdir _pid_dir 0o0755 with Unix.Unix_error(Unix.EEXIST, _, _) -> () );
|
||||
logf "intercepted arguments [%s]" (String.concat "; " (Array.to_list Sys.argv));
|
||||
( match Array.to_list Sys.argv with
|
||||
| [ _; "--wait"; "-t"; "nat"; "-I"; "DOCKER-INGRESS"; "-p"; proto; "--dport"; dport; "-j"; "DNAT"; "--to-destination"; ip_port ] ->
|
||||
let ip, port = parse_ip_port ip_port in
|
||||
insert { proto; dport; ip; port }
|
||||
| [ _; "--wait"; "-t"; "nat"; "-D"; "DOCKER-INGRESS"; "-p"; proto; "--dport"; dport; "-j"; "DNAT"; "--to-destination"; ip_port ] ->
|
||||
let ip, port = parse_ip_port ip_port in
|
||||
delete { proto; dport; ip; port }
|
||||
| _ ->
|
||||
()
|
||||
);
|
||||
Unix.execv _iptables Sys.argv
|
||||
|
Loading…
Reference in New Issue
Block a user