Rust bindings for iptables

Overview

Rust iptables

crates.io Documentation Build Status License

This crate provides bindings for iptables application in Linux (inspired by go-iptables). This crate uses iptables binary to manipulate chains and tables. This source code is licensed under MIT license that can be found in the LICENSE file.

[dependencies]
iptables = "0.4"

Getting started

1- Import the crate iptables and manipulate chains:

let ipt = iptables::new(false).unwrap();

assert!(ipt.new_chain("nat", "NEWCHAINNAME").is_ok());
assert!(ipt.append("nat", "NEWCHAINNAME", "-j ACCEPT").is_ok());
assert!(ipt.exists("nat", "NEWCHAINNAME", "-j ACCEPT").unwrap());
assert!(ipt.delete("nat", "NEWCHAINNAME", "-j ACCEPT").is_ok());
assert!(ipt.delete_chain("nat", "NEWCHAINNAME").is_ok());

For more information, please check the test file in tests folder.

Comments
  • Add `execute`, `get_policy` and `set_policy`

    Add `execute`, `get_policy` and `set_policy`

    While using this library I noticed that I lacked direct access to the iptables-instance and getting/setting the policy on a chain.

    Functions I added:

    • execute: a very thin wrapper around run, only specifying the table, leaving the rest to the user.

      Making run public might be an option, too.

    • get_policy: get the policy for a given table and chain

    • set_policy: set the policy for a given table and chain

    I'm not sure about the names, or the implementations, just let me know if you have better ideas. 👍

    enhancement 
    opened by pitkley 6
  • No error when process does not have correct privledges.

    No error when process does not have correct privledges.

    I was surprised that the library did not report an error when it did not have permission to use iptables. Instead, it failed silently. Would you be alright with accepting a patch to return an error when a process does not have permission to use iptables.

    opened by jpittis 5
  • Allow quoted parameters in rules

    Allow quoted parameters in rules

    This PR adds a SplitQuoted trait which adds the split_quoted function to str. This function allows to split a string on spaces, but keeping double-quoted parts intact. E.g.:

    this is "a test" string
    

    will be split as

    ["this", "is", "a test", "string"].
    

    Double-quotes are removed, since they will be inserted by Command automatically if needed.

    split_quoted is then used where applicable. This allows rules to contain quotes. This can be necessary if one wants to use for example the rule-comment module (see also the added tests):

    -m comment --comment "a comment to describe this rule" -j ACCEPT
    

    becomes

    ["-m", "comment", "--comment", "a comment to describe this rule", "-j", "ACCEPT"]
    

    @yaa110 let me know what you think!

    enhancement 
    opened by pitkley 5
  • Allow nesting of single and double quotes inside rules

    Allow nesting of single and double quotes inside rules

    Previously the regular expression used in split_quoted would erroneously consider a single and double quote as a pair. This made it impossible to have a comment with a nested quote.

    opened by sbohrer 4
  • Panicked at 'called `Result::unwrap()` on an `Err` with null byte

    Panicked at 'called `Result::unwrap()` on an `Err` with null byte

    Hi,

    If you try running this code, the program will crash with a null byte input,

    Input

    00000000  00 01 00 00                                       |....|
    

    Code

    use std::str;
    extern crate iptables;
    
    fn main() {
        let _b = "AAEAAA==";
        let bytes = base64::decode(_b).unwrap();
        let _ok = str::from_utf8(&bytes).unwrap();
        let ipt = iptables::new(false).unwrap();
        ipt.exists("nat", _ok, _ok).unwrap();
    }
    

    Command

    $ export RUST_BACKTRACE=full
    $ cargo run
    

    rustc --version --verbose

    rustc 1.58.1 (db9d1b20b 2022-01-20)
    binary: rustc
    commit-hash: db9d1b20bba1968c1ec1fc49616d4742c1725b4b
    commit-date: 2022-01-20
    host: x86_64-unknown-linux-gnu
    release: 1.58.1
    LLVM version: 13.0.0
    

    Stacktrace

    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: InvalidInput, message: "nul byte found in provided data" }', src/main.rs:13:33
    stack backtrace:
       0:     0x563e70bf130c - std::backtrace_rs::backtrace::libunwind::trace::h09f7e4e089375279
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
       1:     0x563e70bf130c - std::backtrace_rs::backtrace::trace_unsynchronized::h1ec96f1c7087094e
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
       2:     0x563e70bf130c - std::sys_common::backtrace::_print_fmt::h317b71fc9a5cf964
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/sys_common/backtrace.rs:67:5
       3:     0x563e70bf130c - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::he3555b48e7dfe7f0
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/sys_common/backtrace.rs:46:22
       4:     0x563e70c0f21c - core::fmt::write::h513b07ca38f4fb1b
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/core/src/fmt/mod.rs:1149:17
       5:     0x563e70bee005 - std::io::Write::write_fmt::haf8c932b52111354
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/io/mod.rs:1697:15
       6:     0x563e70bf2c90 - std::sys_common::backtrace::_print::h195c38364780a303
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/sys_common/backtrace.rs:49:5
       7:     0x563e70bf2c90 - std::sys_common::backtrace::print::hc09dfdea923b6730
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/sys_common/backtrace.rs:36:9
       8:     0x563e70bf2c90 - std::panicking::default_hook::{{closure}}::hb2e38ec0d91046a3
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/panicking.rs:211:50
       9:     0x563e70bf2845 - std::panicking::default_hook::h60284635b0ad54a8
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/panicking.rs:228:9
      10:     0x563e70bf3344 - std::panicking::rust_panic_with_hook::ha677a669fb275654
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/panicking.rs:606:17
      11:     0x563e70bf2e20 - std::panicking::begin_panic_handler::{{closure}}::h976246fb95d93c31
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/panicking.rs:502:13
      12:     0x563e70bf17b4 - std::sys_common::backtrace::__rust_end_short_backtrace::h38077ee5b7b9f99a
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/sys_common/backtrace.rs:139:18
      13:     0x563e70bf2d89 - rust_begin_unwind
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/panicking.rs:498:5
      14:     0x563e70a023e1 - core::panicking::panic_fmt::h35f3a62252ba0fd2
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/core/src/panicking.rs:107:14
      15:     0x563e70a02473 - core::result::unwrap_failed::hb53671404b9e33c2
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/core/src/result.rs:1613:5
      16:     0x563e70a03fc0 - core::result::Result<T,E>::unwrap::h767f11253a75a42a
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/core/src/result.rs:1295:23
      17:     0x563e70a0329b - new::main::hc9785be4510935fa
                                   at /home/kali/Desktop/source_code_fuzzing_course/Chapter06/arvancloud_libinjection/iptable/src/main.rs:13:5
      18:     0x563e70a0ad9b - core::ops::function::FnOnce::call_once::hfa931b671c38bd5e
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/core/src/ops/function.rs:227:5
      19:     0x563e70a030ee - std::sys_common::backtrace::__rust_begin_short_backtrace::h77fda0fd9ae11ad3
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/sys_common/backtrace.rs:123:18
      20:     0x563e70a03cd1 - std::rt::lang_start::{{closure}}::heec64719c1fef55e
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/rt.rs:145:18
      21:     0x563e70bf0f9b - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h7e688d7cdfeb7e00
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/core/src/ops/function.rs:259:13
      22:     0x563e70bf0f9b - std::panicking::try::do_call::h4be824d2350b44c9
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/panicking.rs:406:40
      23:     0x563e70bf0f9b - std::panicking::try::h0a6fc7affbe5088d
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/panicking.rs:370:19
      24:     0x563e70bf0f9b - std::panic::catch_unwind::h22c320f732ec805e
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/panic.rs:133:14
      25:     0x563e70bf0f9b - std::rt::lang_start_internal::{{closure}}::hd38309c108fe679d
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/rt.rs:128:48
      26:     0x563e70bf0f9b - std::panicking::try::do_call::h8fcaf501f097a28e
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/panicking.rs:406:40
      27:     0x563e70bf0f9b - std::panicking::try::h20e906825f98acc1
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/panicking.rs:370:19
      28:     0x563e70bf0f9b - std::panic::catch_unwind::h8c5234dc632124ef
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/panic.rs:133:14
      29:     0x563e70bf0f9b - std::rt::lang_start_internal::hc4dd8cd3ec4518c2
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/rt.rs:128:20
      30:     0x563e70a03ca0 - std::rt::lang_start::hc5552fe6e509d081
                                   at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/rt.rs:144:17
      31:     0x563e70a032ec - main
      32:     0x7f868bfd47ed - __libc_start_main
      33:     0x563e70a02b4a - _start
      34:                0x0 - <unknown>
    
    

    Thanks, Ramin

    opened by raminfp 2
  • Add -n option to iptables

    Add -n option to iptables

    In some setups iptables takes a long time to list rules when it cannot contact a DNS server. This PR adds the ability to pass the -n flag to iptables to stop the DNS lookups happening. Obviously any listings are returned as raw IPs and un-decoded port numbers when this option is enabled.

    opened by daviessm 2
  • Failing to list iptables rules (-S) when is_numeric = true (-n is an invalid argument with -S)

    Failing to list iptables rules (-S) when is_numeric = true (-n is an invalid argument with -S)

    Hey,

    Since version 0.5.0, the "list" function returns an empty list. This appears to be because the "-n" argument is invalid when used with -S.

    For example:

    $ iptables -t filter -S INPUT -n
    iptables v1.6.1: Illegal option `-n' with this command
    
    Try `iptables -h' or 'iptables --help' for more information.
    

    true => self.get_list(&["-t", table, "-S", chain, "-n"]), from the following code should not contain "-n" in the argument list. The save arguments do not appear to include hostnames in any case.

    /// Lists rules in the table/chain.
        pub fn list(&self, table: &str, chain: &str) -> Result<Vec<String>, Box<dyn Error>> {
            match self.is_numeric {
                false => self.get_list(&["-t", table, "-S", chain]),
                true => self.get_list(&["-t", table, "-S", chain, "-n"]),
            }
        }
    

    Suggested solution:

    /// Lists rules in the table/chain.
        pub fn list(&self, table: &str, chain: &str) -> Result<Vec<String>, Box<dyn Error>> {
            self.get_list(&["-t", table, "-S", chain])
        }
    

    The exists_old_version and list_table functions also appear to have the same issue.

    Thank you for this excellent crate!

    opened by WatakiWatako 0
  • Use explicit error instead of Box<dyn Error>

    Use explicit error instead of Box

    I was called methods in a function like:

    fn foo()->Result<(), Box<dyn Error+Send+Sync>>
    

    So use explicit error instead of Box so that developers can throw out.

    opened by danny-326 0
  • Add and return PermissionDenied error when not root

    Add and return PermissionDenied error when not root

    As discussed in https://github.com/yaa110/rust-iptables/issues/4, the current implementation does not return an error when the process does not have permission to use iptables.

    Fortunately, iptables returns a special status code for permission errors:

    $ sudo iptables --list foobar; echo $?
    iptables: No chain/target/match by that name.
    1
    $ iptables --list; echo $?
    Fatal: can't open lock file /run/xtables.lock: Permission denied
    4
    

    This patch does three things:

    1. Adds the PermissionDenied error.
    2. Maps an exit status of 4 to a PermissionDenied error.
    3. Runs rustfmt.

    I can see why the maintainers might not like 3). The reformat diff is pretty small so I didn't revert it. If you'd like me to revert it and or patch it in a separate commit, please ask.

    Finally, I didn't add any tests to this patch. Likely the code that tests this will need to be run without sudo to trigger the PermissionDenied path. I'm not sure of the nicest way to do this so I was going to wait for the maintainers to discuss.

    Thanks!

    opened by jpittis 5
Releases(0.5.0)
nginx bindings for Rust

nginx-rs This crate provides nginx bindings for Rust. Currently, only Linux is supported. How to Use Add nginx crate to Cargo.toml [dependencies] ngin

ArvanCloud 104 Jan 2, 2023
Rust friendly bindings to *nix APIs

Rust bindings to *nix APIs Documentation (Releases) Nix seeks to provide friendly bindings to various *nix platform APIs (Linux, Darwin, ...). The goa

null 2k Jan 4, 2023
Rust bindings to Windows API

winapi-rs Documentation Official communication channel: #windows-dev on the Rust Community Discord This crate provides raw FFI bindings to all of Wind

Peter Atashian 1.6k Jan 1, 2023
Rust bindings for the FreeBSD capsicum framework

capsicum Contain the awesome! Rust bindings for the FreeBSD capsicum framework for OS capability and sandboxing Prerequisites Rust, Cargo, and FreeBSD

Dan Robertson 52 Dec 5, 2022
Idiomatic inotify wrapper for the Rust programming language

inotify-rs Idiomatic inotify wrapper for the Rust programming language. extern crate inotify; use std::env; use inotify::{ EventMask, Watch

Hanno Braun 220 Dec 26, 2022
Rust library for filesystems in userspace (FUSE)

Rust FUSE - Filesystem in Userspace About fuse-rs is a Rust library crate for easy implementation of FUSE filesystems in userspace. fuse-rs does not j

Andreas Neuhaus 916 Jan 9, 2023
Rust implementation of a FreeBSD jail library

libjail-rs libjail-rs aims to be a rust implementation of the FreeBSD jail(3) library. While feature parity is a goal, a one-to-one implementation of

fubarnetes 38 Sep 27, 2022
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022
An asynchronous Prometheus exporter for iptables

iptables_exporter An asynchronous Prometheus exporter for iptables iptables_exporter runs iptables-save --counter and scrapes the output to build Prom

Kevin K. 21 Dec 29, 2022
An esoteric language/compiler written with Rust and Rust LLVM bindings

MeidoLang (メイドラング) A not so useful and esoteric language. The goal of this project was to contain some quirky or novel syntax in a stack-style program

null 0 Dec 24, 2021
Rust bindings for libinjection

libinjection-rs Rust bindings for libinjection. How to use Add libinjection to dependencies of Cargo.toml: libinjection = "0.2" Import crate: extern c

ArvanCloud 35 Sep 24, 2022
A project for generating C bindings from Rust code

cbindgen   Read the full user docs here! cbindgen creates C/C++11 headers for Rust libraries which expose a public C API. While you could do this by h

Ryan Hunt 1.7k Jan 3, 2023
Automatically generates Rust FFI bindings to C (and some C++) libraries.

bindgen bindgen automatically generates Rust FFI bindings to C (and some C++) libraries. For example, given the C header doggo.h: typedef struct Doggo

The Rust Programming Language 3.2k Jan 4, 2023
Rust-JDBC bindings

jdbc A Rust library that allows you to use JDBC and JDBC drivers. Usage First, add the following to your Cargo.toml: [dependencies] jdbc = "0.1" Next,

Aurora 18 Feb 9, 2022
Lua 5.3 bindings for Rust

rust-lua53 Aims to be complete Rust bindings for Lua 5.3 and beyond. Currently, master is tracking Lua 5.3.3. Requires a Unix-like environment. On Win

J.C. Moyer 150 Dec 14, 2022
Safe Rust bindings to Lua 5.1

rust-lua Copyright 2014 Lily Ballard Description This is a set of Rust bindings to Lua 5.1. The goal is to provide a (relatively) safe interface to Lu

Lily Ballard 124 Jan 5, 2023
mruby safe bindings for Rust

mrusty. mruby safe bindings for Rust mrusty lets you: run Ruby 1.9 files with a very restricted API (without having to install Ruby) reflect Rust stru

Anima 200 Oct 12, 2022
Rust bindings for writing safe and fast native Node.js modules.

Rust bindings for writing safe and fast native Node.js modules. Getting started Once you have the platform dependencies installed, getting started is

The Neon Project 7k Jan 4, 2023
Objective-C Runtime bindings and wrapper for Rust.

Objective-C Runtime bindings and wrapper for Rust. Documentation: http://ssheldon.github.io/rust-objc/objc/ Crate: https://crates.io/crates/objc Messa

Steven Sheldon 336 Jan 2, 2023
High-level Rust bindings to Perl XS API

Perl XS for Rust High-level Rust bindings to Perl XS API. Example xs! { package Array::Sum; sub sum_array(ctx, array: AV) { array.iter().map(|

Vickenty Fesunov 59 Oct 6, 2022