Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save x-yuri/60f0c9163d4d1b4af55b6f8f00229c66 to your computer and use it in GitHub Desktop.
Save x-yuri/60f0c9163d4d1b4af55b6f8f00229c66 to your computer and use it in GitHub Desktop.
iptables-save != iptables-save + iptables-xml + iptables.xslt

iptables-save != iptables-save + iptables-xml + iptables.xslt

$ sudo iptables-save | iptables-xml > /tmp/iptables.xml
$ diff -u <(sudo iptables-save) <(xsltproc /usr/share/xtables/iptables.xslt /tmp/iptables.xml)

Output:

$ diff -u <(sudo iptables-save) <(xsltproc /usr/share/xtables/iptables.xslt /tmp/iptables.xml)
--- /dev/fd/63	2024-10-18 09:52:19.907007760 +0300
+++ /dev/fd/62	2024-10-18 09:52:19.907007760 +0300
@@ -1,119 +1,119 @@
-# Generated by iptables-save v1.8.10 (nf_tables) on Fri Oct 18 09:52:28 2024
+# Generated by iptables.xslt
 *filter
-:INPUT ACCEPT [0:0]
 :FORWARD DROP [0:0]
-:OUTPUT ACCEPT [0:0]
-:DOCKER - [0:0]
 :DOCKER-ISOLATION-STAGE-1 - [0:0]
 :DOCKER-ISOLATION-STAGE-2 - [0:0]
 :DOCKER-USER - [0:0]
--A FORWARD -j DOCKER-USER
--A FORWARD -j DOCKER-ISOLATION-STAGE-1
+:INPUT ACCEPT [0:0]
+:OUTPUT ACCEPT [0:0]
+:DOCKER - [0:0]
+-A FORWARD -j callDOCKER-USER
+-A FORWARD -j callDOCKER-ISOLATION-STAGE-1
 -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
--A FORWARD -o docker0 -j DOCKER
+-A FORWARD -o docker0 -j callDOCKER
...
--A DOCKER-ISOLATION-STAGE-1 -i br-2ff9ef5432af ! -o br-2ff9ef5432af -j DOCKER-ISOLATION-STAGE-2
+-A DOCKER-ISOLATION-STAGE-1 -i br-2ff9ef5432af ! -o br-2ff9ef5432af -j callDOCKER-ISOLATION-STAGE-2
 -A DOCKER-ISOLATION-STAGE-1 -j RETURN
 -A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
 -A DOCKER-ISOLATION-STAGE-2 -o br-dd277d2d041c -j DROP
@@ -139,16 +139,16 @@
 -A DOCKER-ISOLATION-STAGE-2 -j RETURN
 -A DOCKER-USER -j RETURN
 COMMIT
-# Completed on Fri Oct 18 09:52:28 2024
-# Generated by iptables-save v1.8.10 (nf_tables) on Fri Oct 18 09:52:28 2024
+# Completed
+# Generated by iptables.xslt
 *nat
-:PREROUTING ACCEPT [331:49348]
-:INPUT ACCEPT [0:0]
-:OUTPUT ACCEPT [34434:5630241]
-:POSTROUTING ACCEPT [34434:5630241]
+:PREROUTING ACCEPT [328:48904]
+:OUTPUT ACCEPT [33991:5565567]
+:POSTROUTING ACCEPT [33991:5565567]
 :DOCKER - [0:0]
--A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
--A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
+:INPUT ACCEPT [0:0]
+-A PREROUTING -m addrtype --dst-type LOCAL -j callDOCKER
+-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j callDOCKER
 -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
 -A POSTROUTING -s 172.25.0.0/16 ! -o br-dd277d2d041c -j MASQUERADE
 -A POSTROUTING -s 172.24.0.0/16 ! -o br-c72c7cc97efc -j MASQUERADE
@@ -192,4 +192,4 @@
 -A DOCKER -i br-719e39a482c9 -j RETURN
 -A DOCKER -i br-2ff9ef5432af -j RETURN
 COMMIT
-# Completed on Fri Oct 18 09:52:28 2024
+# Completed

Do note the -j callDOCKER parts.

That's because the iptables-rules/table/chain/rule/actions/call and iptables-rules/table/chain/rule/actions/* templates has the same priority, and the last one wins.

Let's swap them:

a.xslt:

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="ISO-8859-1"/>
  <xsl:template match="xsl:transform">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates select="node()[following-sibling::*[@match = 'iptables-rules/table/chain/rule/actions/call']]"/>
      <xsl:apply-templates select="node()[preceding-sibling::*[@match = 'iptables-rules/table/chain/rule/actions/call'] and following-sibling::*[@match = 'iptables-rules/table/chain/rule/actions/*']]"/>
      <xsl:apply-templates select="node()[@match = 'iptables-rules/table/chain/rule/actions/*']"/>
      <xsl:apply-templates select="node()[@match = 'iptables-rules/table/chain/rule/actions/call']"/>
      <xsl:apply-templates select="node()[preceding-sibling::*[@match = 'iptables-rules/table/chain/rule/actions/*']]"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
</xsl:transform>
$ xsltproc /tmp/a.xslt /usr/share/xtables/iptables.xslt > /tmp/b.xslt
$ diff -u /usr/share/xtables/iptables.xslt <(xsltproc /tmp/a.xslt /usr/share/xtables/iptables.xslt)

Output:

--- /usr/share/xtables/iptables.xslt	2024-07-03 19:01:49.000000000 +0300
+++ /dev/fd/63	2024-10-18 10:43:22.736720478 +0300
@@ -7,9 +7,9 @@
      This sample usage outputs roughly want goes in
        iptables-save | iptables-xml -c | xsltproc iptables.xslt -
      -->
-<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-  <xsl:output method = "text" />
-  <xsl:strip-space elements="*" />
+<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+  <xsl:output method="text"/>
+  <xsl:strip-space elements="*"/>
 
   <!-- output conditions of a rule but not an action -->
   <xsl:template match="iptables-rules/table/chain/rule/conditions/*">
@@ -29,18 +29,21 @@
   <xsl:template match="iptables-rules/table/chain/rule/actions/goto">
     <xsl:text> -g </xsl:text>
     <xsl:apply-templates select="*"/>
-    <xsl:text>&#xA;</xsl:text>
-  </xsl:template>
-  <xsl:template match="iptables-rules/table/chain/rule/actions/call">
-    <xsl:text> -j </xsl:text>
-    <xsl:apply-templates select="*"/>
-    <xsl:text>&#xA;</xsl:text>
+    <xsl:text>
+</xsl:text>
   </xsl:template>
+  
   <!-- all other actions are module actions -->
   <xsl:template match="iptables-rules/table/chain/rule/actions/*">
     <xsl:text> -j </xsl:text><xsl:value-of select="name()"/>
     <xsl:apply-templates select="*"/>
-    <xsl:text>&#xA;</xsl:text>
+    <xsl:text>
+</xsl:text>
+  </xsl:template><xsl:template match="iptables-rules/table/chain/rule/actions/call">
+    <xsl:text> -j </xsl:text>
+    <xsl:apply-templates select="*"/>
+    <xsl:text>
+</xsl:text>
   </xsl:template>
   
   <!-- all child action nodes -->
@@ -69,7 +72,7 @@
       <xsl:text> </xsl:text>
     </xsl:if>
     <xsl:text>-A </xsl:text><!-- a rule must be under a chain -->
-    <xsl:value-of select="../@name" />
+    <xsl:value-of select="../@name"/>
     <xsl:apply-templates select="conditions"/>
   </xsl:template>
 
@@ -89,14 +92,17 @@
       <xsl:otherwise>
         <!-- no need to loop if there are no actions, just output conditions -->
         <xsl:call-template name="rule-head"/>
-        <xsl:text>&#xA;</xsl:text>
+        <xsl:text>
+</xsl:text>
       </xsl:otherwise>
     </xsl:choose>
   </xsl:template>
 
   <xsl:template match="iptables-rules/table">
-    <xsl:text># Generated by iptables.xslt&#xA;</xsl:text>
-    <xsl:text>*</xsl:text><xsl:value-of select="@name"/><xsl:text>&#xA;</xsl:text>
+    <xsl:text># Generated by iptables.xslt
+</xsl:text>
+    <xsl:text>*</xsl:text><xsl:value-of select="@name"/><xsl:text>
+</xsl:text>
     <!-- Loop through each chain and output the chain header -->
     <xsl:for-each select="chain">
       <xsl:text>:</xsl:text>
@@ -108,11 +114,14 @@
       </xsl:choose>
       <xsl:text> </xsl:text>
       <xsl:call-template name="counters"><xsl:with-param name="node" select="."/></xsl:call-template>
-      <xsl:text>&#xA;</xsl:text>
+      <xsl:text>
+</xsl:text>
     </xsl:for-each>
     <!-- Loop through each chain and output the rules -->
     <xsl:apply-templates select="node()"/>
-    <xsl:text>COMMIT&#xA;# Completed&#xA;</xsl:text>
+    <xsl:text>COMMIT
+# Completed
+</xsl:text>
   </xsl:template>
   
   <xsl:template name="counters">
$ diff -u <(sudo iptables-save) <(xsltproc /tmp/b.xslt /tmp/iptables.xml)

Output:

--- /dev/fd/63	2024-10-18 10:43:57.503220210 +0300
+++ /dev/fd/62	2024-10-18 10:43:57.503220210 +0300
@@ -1,12 +1,12 @@
-# Generated by iptables-save v1.8.10 (nf_tables) on Fri Oct 18 10:43:57 2024
+# Generated by iptables.xslt
 *filter
-:INPUT ACCEPT [0:0]
 :FORWARD DROP [0:0]
-:OUTPUT ACCEPT [0:0]
-:DOCKER - [0:0]
 :DOCKER-ISOLATION-STAGE-1 - [0:0]
 :DOCKER-ISOLATION-STAGE-2 - [0:0]
 :DOCKER-USER - [0:0]
+:INPUT ACCEPT [0:0]
+:OUTPUT ACCEPT [0:0]
+:DOCKER - [0:0]
 -A FORWARD -j DOCKER-USER
 -A FORWARD -j DOCKER-ISOLATION-STAGE-1
 -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
@@ -139,14 +139,14 @@
 -A DOCKER-ISOLATION-STAGE-2 -j RETURN
 -A DOCKER-USER -j RETURN
 COMMIT
-# Completed on Fri Oct 18 10:43:57 2024
-# Generated by iptables-save v1.8.10 (nf_tables) on Fri Oct 18 10:43:57 2024
+# Completed
+# Generated by iptables.xslt
 *nat
-:PREROUTING ACCEPT [371:55354]
-:INPUT ACCEPT [0:0]
-:OUTPUT ACCEPT [38614:6238326]
-:POSTROUTING ACCEPT [38614:6238326]
+:PREROUTING ACCEPT [328:48904]
+:OUTPUT ACCEPT [33991:5565567]
+:POSTROUTING ACCEPT [33991:5565567]
 :DOCKER - [0:0]
+:INPUT ACCEPT [0:0]
 -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
 -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
 -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
@@ -192,4 +192,4 @@
 -A DOCKER -i br-719e39a482c9 -j RETURN
 -A DOCKER -i br-2ff9ef5432af -j RETURN
 COMMIT
-# Completed on Fri Oct 18 10:43:57 2024
+# Completed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment