diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm
index 16dd68439..d03619f37 100644
--- a/Shorewall/Perl/Shorewall/Chains.pm
+++ b/Shorewall/Perl/Shorewall/Chains.pm
@@ -3254,6 +3254,16 @@ sub set_mss( $$$ ) {
#
# Interate over all zones with 'mss=' settings adding TCPMSS rules as appropriate.
#
+sub imatch_source_dev( $;$ );
+sub imatch_dest_dev( $;$ );
+sub imatch_source_net( $;$\$ );
+sub imatch_dest_net( $ );
+
+sub newmsschain( ) {
+ my $seq = $chainseq{filter}++;
+ "~mss${seq}";
+}
+
sub setup_zone_mss() {
for my $zone ( all_zones ) {
my $zoneref = find_zone( $zone );
@@ -3261,6 +3271,29 @@ sub setup_zone_mss() {
set_mss( $zone, $zoneref->{options}{in_out}{mss}, '' ) if $zoneref->{options}{in_out}{mss};
set_mss( $zone, $zoneref->{options}{in}{mss}, '_in' ) if $zoneref->{options}{in}{mss};
set_mss( $zone, $zoneref->{options}{out}{mss}, '_out' ) if $zoneref->{options}{out}{mss};
+
+ my $hosts = find_zone_hosts_by_option( $zone, 'mss' );
+
+ for my $hostref ( @$hosts ) {
+ my $mss = $hostref->[4];
+ my @mssmatch = have_capability( 'TCPMSS_MATCH' ) ? ( tcpmss => "--mss $mss:" ) : ();
+ my @sourcedev = imatch_source_dev $hostref->[0];
+ my @destdev = imatch_dest_dev $hostref->[0];
+ my @source = imatch_source_net $hostref->[2];
+ my @dest = imatch_dest_net $hostref->[2];
+ my @ipsecin = (have_ipsec ? ( policy => "--pol $hostref->[1] --dir in" ) : () );
+ my @ipsecout = (have_ipsec ? ( policy => "--pol $hostref->[1] --dir out" ) : () );
+
+ my $chainref = new_chain 'filter', newmsschain;
+ my $target = source_exclusion( $hostref->[3], $chainref );
+
+ add_ijump $chainref, j => 'TCPMSS', targetopts => "--set-mss $mss", p => 'tcp --tcp-flags SYN,RST SYN';
+
+ for my $zone1 ( all_zones ) {
+ add_ijump ensure_chain( 'filter', rules_chain( $zone, $zone1 ) ), j => $target , @sourcedev, @source, p => 'tcp --tcp-flags SYN,RST SYN', @mssmatch, @ipsecin ;
+ add_ijump ensure_chain( 'filter', rules_chain( $zone1, $zone ) ), j => $target , @destdev, @dest, p => 'tcp --tcp-flags SYN,RST SYN', @mssmatch, @ipsecout ;
+ }
+ }
}
}
diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm
index 5c04690e8..55c21090f 100644
--- a/Shorewall/Perl/Shorewall/Zones.pm
+++ b/Shorewall/Perl/Shorewall/Zones.pm
@@ -83,6 +83,7 @@ our @EXPORT = qw( NOTHING
compile_updown
validate_hosts_file
find_hosts_by_option
+ find_zone_hosts_by_option
find_zones_by_option
all_ipsets
have_ipsec
@@ -309,6 +310,7 @@ sub initialize( $$ ) {
broadcast => 1,
destonly => 1,
sourceonly => 1,
+ mss => 1,
);
%zonetypes = ( 1 => 'firewall', 2 => 'ipv4', 4 => 'bport4', 8 => 'ipsec4', 16 => 'vserver' );
} else {
@@ -335,6 +337,7 @@ sub initialize( $$ ) {
maclist => 1,
routeback => 1,
tcpflags => 1,
+ mss => 1,
);
%zonetypes = ( 1 => 'firewall', 2 => 'ipv6', 4 => 'bport6', 8 => 'ipsec4', 16 => 'vserver' );
}
@@ -1868,6 +1871,10 @@ sub process_host( ) {
warning_message "The 'norfc1918' host option is no longer supported"
} elsif ( $option eq 'blacklist' ) {
$zoneref->{options}{in}{blacklist} = 1;
+ } elsif ( $option =~ /^mss=(\d+)$/ ) {
+ fatal_error "Invalid mss ($1)" unless $1 >= 500;
+ $options{mss} = $1;
+ $zoneref->{options}{complex} = 1;
} elsif ( $validhostoptions{$option}) {
fatal_error qq(The "$option" option is not allowed with Vserver zones) if $type & VSERVER && ! ( $validhostoptions{$option} & IF_OPTION_VSERVER );
$options{$option} = 1;
@@ -1944,7 +1951,7 @@ sub have_ipsec() {
#
# Returns a reference to a array of host entries. Each entry is a
-# reference to an array containing ( interface , polciy match type {ipsec|none} , network , exclusions );
+# reference to an array containing ( interface , polciy match type {ipsec|none} , network , exclusions, value );
#
sub find_hosts_by_option( $ ) {
my $option = $_[0];
@@ -1954,9 +1961,9 @@ sub find_hosts_by_option( $ ) {
while ( my ($type, $interfaceref) = each %{$zones{$zone}{hosts}} ) {
while ( my ( $interface, $arrayref) = ( each %{$interfaceref} ) ) {
for my $host ( @{$arrayref} ) {
- if ( $host->{options}{$option} ) {
+ if ( my $value = $host->{options}{$option} ) {
for my $net ( @{$host->{hosts}} ) {
- push @hosts, [ $interface, $host->{ipsec} , $net , $host->{exclusions}];
+ push @hosts, [ $interface, $host->{ipsec} , $net , $host->{exclusions}, $value ];
}
}
}
@@ -1973,6 +1980,30 @@ sub find_hosts_by_option( $ ) {
\@hosts;
}
+#
+# As above but for a single zone
+#
+sub find_zone_hosts_by_option( $$ ) {
+ my ($zone, $option ) = @_;
+ my @hosts;
+
+ unless ( $zones{$zone}{type} & FIREWALL ) {
+ while ( my ($type, $interfaceref) = each %{$zones{$zone}{hosts}} ) {
+ while ( my ( $interface, $arrayref) = ( each %{$interfaceref} ) ) {
+ for my $host ( @{$arrayref} ) {
+ if ( my $value = $host->{options}{$option} ) {
+ for my $net ( @{$host->{hosts}} ) {
+ push @hosts, [ $interface, $host->{ipsec} , $net , $host->{exclusions}, $value ];
+ }
+ }
+ }
+ }
+ }
+ }
+
+ \@hosts;
+}
+
#
# Returns a reference to a list of zones with the passed in/out option
#
diff --git a/Shorewall/manpages/shorewall-hosts.xml b/Shorewall/manpages/shorewall-hosts.xml
index d2eed8a0a..8cbf91908 100644
--- a/Shorewall/manpages/shorewall-hosts.xml
+++ b/Shorewall/manpages/shorewall-hosts.xml
@@ -118,32 +118,6 @@
must have no embedded white space.
-
- maclist
-
-
- Connection requests from these hosts are compared
- against the contents of shorewall-maclist(5). If
- this option is specified, the interface must be an ethernet
- NIC or equivalent and must be up before Shorewall is
- started.
-
-
-
-
- routeback
-
-
- Shorewall should set up the infrastructure to pass
- packets from this/these address(es) back to themselves. This
- is necessary if hosts in this group use the services of a
- transparent proxy that is a member of the group or if DNAT is
- used to send requests originating from this group to a server
- in the group.
-
-
-
blacklist
@@ -154,48 +128,6 @@
-
- tcpflags
-
-
- Packets arriving from these hosts are checked for
- certain illegal combinations of TCP flags. Packets found to
- have such a combination of flags are handled according to the
- setting of TCP_FLAGS_DISPOSITION after having been logged
- according to the setting of TCP_FLAGS_LOG_LEVEL.
-
-
-
-
- nosmurfs
-
-
- This option only makes sense for ports on a
- bridge.
-
- Filter packets for smurfs (packets with a broadcast
- address as the source).
-
- Smurfs will be optionally logged based on the setting of
- SMURF_LOG_LEVEL in shorewall.conf(5). After
- logging, the packets are dropped.
-
-
-
-
- ipsec
-
-
- The zone is accessed via a kernel 2.6 ipsec SA. Note
- that if the zone named in the ZONE column is specified as an
- IPSEC zone in the shorewall-zones(5) file
- then you do NOT need to specify the 'ipsec' option
- here.
-
-
-
broadcast
@@ -229,6 +161,86 @@
net(s).
+
+
+ ipsec
+
+
+ The zone is accessed via a kernel 2.6 ipsec SA. Note
+ that if the zone named in the ZONE column is specified as an
+ IPSEC zone in the shorewall-zones(5) file
+ then you do NOT need to specify the 'ipsec' option
+ here.
+
+
+
+
+ maclist
+
+
+ Connection requests from these hosts are compared
+ against the contents of shorewall-maclist(5). If
+ this option is specified, the interface must be an ethernet
+ NIC or equivalent and must be up before Shorewall is
+ started.
+
+
+
+
+ mss=mss
+
+
+ Added in Shorewall 4.5.2. When present, causes the TCP
+ mss for new connections to/from the hosts given in the HOST(S)
+ column to be clamped at the specified
+ mss.
+
+
+
+
+ nosmurfs
+
+
+ This option only makes sense for ports on a
+ bridge.
+
+ Filter packets for smurfs (packets with a broadcast
+ address as the source).
+
+ Smurfs will be optionally logged based on the setting of
+ SMURF_LOG_LEVEL in shorewall.conf(5). After
+ logging, the packets are dropped.
+
+
+
+
+ routeback
+
+
+ Shorewall should set up the infrastructure to pass
+ packets from this/these address(es) back to themselves. This
+ is necessary if hosts in this group use the services of a
+ transparent proxy that is a member of the group or if DNAT is
+ used to send requests originating from this group to a server
+ in the group.
+
+
+
+
+ tcpflags
+
+
+ Packets arriving from these hosts are checked for
+ certain illegal combinations of TCP flags. Packets found to
+ have such a combination of flags are handled according to the
+ setting of TCP_FLAGS_DISPOSITION after having been logged
+ according to the setting of TCP_FLAGS_LOG_LEVEL.
+
+
diff --git a/Shorewall6/manpages/shorewall6-hosts.xml b/Shorewall6/manpages/shorewall6-hosts.xml
index d51247d08..dfc5c8663 100644
--- a/Shorewall6/manpages/shorewall6-hosts.xml
+++ b/Shorewall6/manpages/shorewall6-hosts.xml
@@ -120,19 +120,6 @@
the list must have no embedded white space.
-
- routeback
-
-
- shorewall6 should set up the infrastructure to pass
- packets from this/these address(es) back to themselves. This
- is necessary if hosts in this group use the services of a
- transparent proxy that is a member of the group or if DNAT is
- used to send requests originating from this group to a server
- in the group.
-
-
-
blacklist
@@ -143,18 +130,6 @@
-
- tcpflags
-
-
- Packets arriving from these hosts are checked for
- certain illegal combinations of TCP flags. Packets found to
- have such a combination of flags are handled according to the
- setting of TCP_FLAGS_DISPOSITION after having been logged
- according to the setting of TCP_FLAGS_LOG_LEVEL.
-
-
-
ipsec
@@ -167,6 +142,43 @@
here.
+
+
+ mss=mss
+
+
+ Added in Shorewall 4.5.2. When present, causes the TCP
+ mss for new connections to/from the hosts given in the HOST(S)
+ column to be clamped at the specified
+ mss.
+
+
+
+
+ routeback
+
+
+ shorewall6 should set up the infrastructure to pass
+ packets from this/these address(es) back to themselves. This
+ is necessary if hosts in this group use the services of a
+ transparent proxy that is a member of the group or if DNAT is
+ used to send requests originating from this group to a server
+ in the group.
+
+
+
+
+ tcpflags
+
+
+ Packets arriving from these hosts are checked for
+ certain illegal combinations of TCP flags. Packets found to
+ have such a combination of flags are handled according to the
+ setting of TCP_FLAGS_DISPOSITION after having been logged
+ according to the setting of TCP_FLAGS_LOG_LEVEL.
+
+