Postfix SPF

Posted by alex almazan Wed, 30 Jul 2008 13:18:00 GMT

This article is to ouline the specifics for implementing SPF policy framework for Postfix provided in Redhat Enterprise Linux (es4/es5).

1.) First install all the necessary perl modules via RPM that you will require:

http://dag.wieers.com/rpm/packages/perl-Net-Address-IPv4-Local/ http://dag.wieers.com/rpm/packages/perl-NetAddr-IP/ http://dag.wieers.com/rpm/packages/perl-Mail-SPF/

(additional RPMs may be required) I would recommend that you refrain from installing via CPAN as a mix of RPM installed and CPAN installed modules can lead to issues in the future.

2.) Obtain and install the SPF perl script
cd /usr/src
wget http://www.openspf.org/blobs/postfix-policyd-spf-perl-2.001.tar.gz
tar xvfz postfix-policyd-spf-perl-2.001.tar.gz
cd postfix-policyd-spf-perl-2.001
cp postfix-policyd-spf-perl /usr/libexec/postfix/postfix-policyd-spf-perl
chomd o+x /usr/libexec/postfix/postfix-policyd-spf-perl
Ensure that you set the script to executable, or errors such as these are recieved
warning: command /usr/bin/perl exit status 2
postfix/smtpd: warning: premature end-of-input on private/policy while reading input attribute name
3.)Next, edit the postfix configuration file ’/etc/postfix/master.cf’ This line should be appended to the end of the configuration.
policy  unix  -       n       n       -       -       spawn
        user=nobody argv=/usr/bin/perl /usr/lib/postfix/policyd-spf-perl
4.)Next open /etc/postfix/main.cf and find the directive “smtpd_recipient_restrictions” You should have reject_unauth_destination in that directive, and right after reject_unauth_destination add ‘check_policy_service unix:private/policy’
smtpd_recipient_restrictions =permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination,check_policy_service unix:private/policy
important ensure that you specify “check_policy_service” AFTER “reject_unauth_destination” or else you will have an open relay!

Plesk TLS

Posted by alex almazan Mon, 21 Jul 2008 08:21:22 GMT

The following syntax will help determine any issues with the certificates loaded for TLS: -
openssl s_client -connect 127.0.0.1:25 -starttls smtp -debug

Your mileage will vary

EXT3 online resize

Posted by alex almazan Tue, 03 Jun 2008 06:32:00 GMT

Introduction of an additional drive into a RAID array to expand capacity requires additional steps in the OS to expand the partition without data loss.

First, fdisk the device and delete the “EXTENDED” partition that you are looking to resize, in this instance partition 4.

[root@app1 ~]# fdisk /dev/sda

The number of cylinders for this disk is set to 53309.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)

Command (m for help): p

Disk /dev/sda: 438.4 GB, 438489317376 bytes
255 heads, 63 sectors/track, 53309 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda2              14         274     2096482+  83  Linux
/dev/sda3             275         405     1052257+  82  Linux swap
/dev/sda4             406       35539   282213855    5  Extended
/dev/sda5             406       35539   282213823+  83  Linux
Command (m for help): d
Partition number (1-5): 4

Command (m for help): p

Disk /dev/sda: 438.4 GB, 438489317376 bytes
255 heads, 63 sectors/track, 53309 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda2              14         274     2096482+  83  Linux
/dev/sda3             275         405     1052257+  82  Linux swap
Once this has been removed the partition should be re-created as extended, then a primary partition introduced
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
e
Selected partition 4
First cylinder (406-53309, default 406): 
Using default value 406
Last cylinder or +size or +sizeM or +sizeK (406-53309, default 53309): 
Using default value 53309

Command (m for help): p

Disk /dev/sda: 438.4 GB, 438489317376 bytes
255 heads, 63 sectors/track, 53309 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda2              14         274     2096482+  83  Linux
/dev/sda3             275         405     1052257+  82  Linux swap
/dev/sda4             406       53309   424951380    5  Extended
Now introduce a primary partition on the extended NOTICE- The cylinder in use of the removed partition should be noted as the subsequent introduction of the new partition will require this detail in order to preserve the data
Command (m for help): n
First cylinder (406-53309, default 406): 
Using default value 406
Last cylinder or +size or +sizeM or +sizeK (406-53309, default 53309): 
Using default value 53309

Command (m for help): p

Disk /dev/sda: 438.4 GB, 438489317376 bytes
255 heads, 63 sectors/track, 53309 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda2              14         274     2096482+  83  Linux
/dev/sda3             275         405     1052257+  82  Linux swap
/dev/sda4             406       53309   424951380    5  Extended
/dev/sda5             406       53309   424951348+  83  Linux
write the changes and exit
Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table.
The new table will be used at the next reboot.
Syncing disks.

A reboot of the system is required. The final step is ‘ext2online’ of ’/’
[root@app1 ~]# ext2online /
ext2online v1.1.18 - 2001/03/18 for EXT2FS 0.5b
Partition expanded from this:
[root@app1 ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda5             265G  256G  9.9G  97% /
/dev/sda1              99M   12M   82M  13% /boot
none                  2.0G     0  2.0G   0% /dev/shm
/dev/sda2             2.0G   53M  1.9G   3% /tmp
to this
[root@app1 ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda5             399G  227G  173G  57% /
/dev/sda1              99M   12M   82M  13% /boot
none                  2.0G     0  2.0G   0% /dev/shm
/dev/sda2             2.0G   52M  1.9G   3% /tmp

IPTables and libwrap

Posted by alex almazan Sat, 03 May 2008 06:02:00 GMT

Secruing Services

NOTE choose the easiest otions first such as TCPwrappers to control service connections.

/etc/hosts.allow
/etc/hosts.deny

man page syntax identical:

basic syntax is : : ex. to allow ssh connections for SSH
sshd: 192.168.2.200

These files are parse in the following order:

/etc/hosts.allow If the configuration of this file permits the requested connection, the connection is immediately allowed
/etc/hosts.deny If the configuration of this file does not permit the requested connection, the connection is immediately refused.

TCP wrappers can only be run on packages compiled agains libwrap. ldd can be used to check if it has been compiled against libwrap.

example for checking with ‘ldd’

[root@station home]# ldd /usr/sbin/sendmail.sendmail |grep wrap
        libwrap.so.0 => /usr/lib/libwrap.so.0 (0x006a8000)
portmap is another service , but it is a bit convoluted:
[root@station home]# strings /sbin/portmap |grep hosts
hosts_access_verbose
hosts_allow_table
hosts_deny_table
/etc/hosts.allow
/etc/hosts.deny

here are others configured against libwrap:

ssh,sendmail,xinetd,vsftpd,stunnel - Two choices when configuring hosts.allow|deny in the following example. permit connections for vsftp from 10.1.1.1, but block from 10.0.0.0/255.0.0.0

you can make seperate entries in both:

hosts.deny

vsftpd: 10.0.0.0/255.0.0.0

hosts.allow

vsftpd: 10.1.1.1

Or you can add this to just the deny file as suggested with the keyword

‘EXCEPT’

# hosts.deny    This file describes the names of the hosts which are
#               *not* allowed to use the local INET services, as decided
#               by the '/usr/sbin/tcpd' server.
#
# The portmap line is redundant, but it is left to remind you that
# the new secure portmap uses hosts.deny and hosts.allow.  In particular
# you should know that NFS uses portmap!
#vsftpd: 10.0.0.0/255.0.0.0
vsftpd: 10.0.0.0/255.0.0.0 EXCEPT 10.1.1.1

‘ALL’ can be used in the config as the service or the connecting source:

ALL:ALL EXCEPT 192.168.1.1 

In /etc/hosts.deny to block all service affected by libwrap, but open to the one source or

ALL:ALL 
In hosts.deny, with explicit service permissions in /etc/hosts.allow.

‘DenyHosts is a script from sourceforge that you can run from cron to parse /var/log/secure to review those that have attempted multiple brute force attacks’ (‘swatch’-‘pamABL’ are similar scripts, but modify iptables)

IPTables

Permits packet filterring at the kernel level. Netfilter is the kernel module that does the dirty work, iptables helps define the rules/chains to permit/deny through the kernels ip stack.

INPUT responsible for inbound destined for the server
OUTPUT responsible for outbound traffic leaving the server
FORWARD across the servers interfaces
iptables -L 

lists or prints the current rules in place

iptables -L -n -v -t nat

iptables-save writes to /etc/sysconfig/iptables. (keeping rules persistent,they must be apart of this file)

Configuration parsed from top to bottom. IPTables will response based on the first match. If there is no specific match, the chain policy will apply.

IPtables uses targets to determine what action will be taken if traffic matches an existing rule.

DROP will drop package and send no info to the user
REJECT will send a connection refused notice back to the sender
ACCEPT will permit the connection
LOG will log the connection attempt

IPTables syntax rule formulation help:-

What chain will the rule apply to?

-A INPUT
What patterns(s) would you like to check for?
-s 192.168.2.100

To make the rule active, you can add the following info to /etc/sysconfig/iptables

-A INPUT -s 192.168.2.100 -j REJECT

You can also configure the rule from CLI with

iptables -A INPUT -s 192.168.2.100 -j REJECT

What should IPTables do when a matching pattern is found?

-j REJECT

You can also match on the following criteria:

-i incoming interface
-p protocol
-s source ip address
-d destination ip address
-dport destination port

Saving the rules service iptables-save

iptables -D INPUT 3 

This command will delete the third rule in the INPUT CHAIN A quick means of identifying line number is:

iptables -L --line-numbers
iptables -D INPUT <rule> 

This command will delete the specific rule from the INPUT chain.

iptables -F 

This command will flush the IPTables rulesets

system-config-securitylevel utility used to create the following config

[root@station sysconfig]# cat iptables
# Firewall configuration written by system-config-securitylevel
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT                             
---(permit the loopback)
-A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p 50 -j ACCEPT                             
---(for ipsec)
-A RH-Firewall-1-INPUT -p 51 -j ACCEPT                             
---(for ipsec)
-A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
---(multicast/Avahi)
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT            ---(for cups)
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT            ---(for cups)
-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j
ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 25 -j
ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j
ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 137 -j
ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 138 -j
ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 139 -j
ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 445 -j
ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j
ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j
ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 110 -j
ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 143 -j
ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 837 -j
ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 993 -j
ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 995 -j
ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT
created the following chain to apply the rules in /etc/sysconfig/iptables:
RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
This and the allowed outlined rules above where automagically put in place. Considered a mostly closed configuration based on the ‘ACCEPT’ policy. If you need to use the rulesets generated by ‘system’ utlities comment out the last rule to keep from failing the test
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
service iptables panic changes to a default drop policy
[root@station sysconfig]# service iptables panic
Flushing firewall rules:                                   [  OK  ]
Setting chains to policy DROP: filter                      [  OK  ]
[root@station13 sysconfig]# iptables -L -v
Chain INPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source              
destination

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source              
destination

Chain OUTPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source              
destination
Put these back in place to permit connections
[root@station sysconfig]# iptables -P INPUT ACCEPT
[root@station sysconfig]# iptables -P OUTPUT ACCEPT
[root@station sysconfig]# iptables -L -v
Chain INPUT (policy ACCEPT 1 packets, 78 bytes)
 pkts bytes target     prot opt in     out     source              
destination

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source              
destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source              
destination

configure your mail server not to accept connections from the 192.168.1.0/24 network, EXCEPT for the 192.168.1.2 host:

iptables example

[root@station etc]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
REJECT     all  --  10.0.0.0/8           anywhere            reject-with
icmp-port-unreachable
ACCEPT     tcp  --  192.168.1.2          anywhere            tcp dpt:smtp
REJECT     tcp  --  192.168.1.0/24       anywhere            tcp dpt:smtp
reject-with icmp-port-unreachable

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
[root@station etc]# cat /etc/sysconfig/iptables
# Generated by iptables-save v1.3.5 on Thu Aug  9 16:08:07 2007
*filter
:INPUT ACCEPT [134:32679]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [47:4569]
-A INPUT -s 10.0.0.0/255.0.0.0 -j REJECT --reject-with icmp-port-unreachable
-A INPUT -s 192.168.1.2/255.255.255.255 -p tcp -m tcp --dport 25 -j ACCEPT
-A INPUT -s 192.168.1.0/255.255.255.0 -p tcp -m tcp --dport 25 -j REJECT
--reject-with icmp-port-unreachable

tcp wrapper example ( since this said sendmail, it must be the MTA running, not postfix, as postfix is not compiled against libwrap)

alternatives—config mta

then /etc/hosts.deny:

[root@station etc]# cat /etc/hosts.deny
#
# hosts.deny    This file describes the names of the hosts which are
#               *not* allowed to use the local INET services, as decided
#               by the '/usr/sbin/tcpd' server.
#
# The portmap line is redundant, but it is left to remind you that
# the new secure portmap uses hosts.deny and hosts.allow.  In particular
# you should know that NFS uses portmap!
#vsftpd: 10.0.0.0/255.0.0.0
#vsftpd: 10.0.0.0/255.0.0.0 EXCEPT 10.1.1.1
sendmail: 192.168.1.0/24 EXCEPT 192.168.1.2
followed with rules for governing port 110/143: -
[root@station etc]# cat /etc/sysconfig/iptables
# Generated by iptables-save v1.3.5 on Thu Aug  9 16:08:07 2007
*filter
:INPUT ACCEPT [134:32679]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [47:4569]
-A INPUT -s 192.168.1.2/255.255.255.255 -p tcp -m tcp --dport 25 -j ACCEPT
-A INPUT -s 192.168.1.2/255.255.255.255 -p tcp -m tcp --dport 143 -j ACCEPT
-A INPUT -s 192.168.1.2/255.255.255.255 -p tcp -m tcp --dport 993 -j ACCEPT
-A INPUT -s 192.168.1.2/255.255.255.255 -p tcp -m tcp --dport 110 -j ACCEPT
-A INPUT -s 192.168.1.2/255.255.255.255 -p tcp -m tcp --dport 995 -j ACCEPT
-A INPUT -s 192.168.1.0/255.255.255.0 -p tcp -m tcp --dport 25 -j REJECT --reject-with icmp-port-unreachable
-A INPUT -s 192.168.1.0/255.255.255.0 -p tcp -m tcp --dport 143 -j REJECT --reject-with icmp-port-unreachable
-A INPUT -s 192.168.1.0/255.255.255.0 -p tcp -m tcp --dport 993 -j REJECT --reject-with icmp-port-unreachable
-A INPUT -s 192.168.1.0/255.255.255.0 -p tcp -m tcp --dport 110 -j REJECT --reject-with icmp-port-unreachable
-A INPUT -s 192.168.1.0/255.255.255.0 -p tcp -m tcp --dport 995 -j REJECT --reject-with icmp-port-unreachable

DoveCot SSL

Posted by alex almazan Sat, 03 May 2008 05:42:00 GMT

In order to configure SSL for dovecot, the following is recommended
[root@station ]# cd /etc/pki/
[root@station pki]# ls
CA  dovecot  nssdb  rpm-gpg  tls
[root@station pki]# find . -name Makefile
./tls/certs/Makefile
[root@station pki]# cd tls/certs/
[root@station certs]# ls
ca-bundle.crt  localhost.crt  make-dummy-cert  Makefile
[root@station certs]# make
This makefile allows you to create:
  o public/private key pairs
  o SSL certificate signing requests (CSRs)
  o self-signed SSL test certificates

To create a key pair, run "make SOMETHING.key".
To create a CSR, run "make SOMETHING.csr".
To create a test certificate, run "make SOMETHING.crt".
To create a key and a test certificate in one file, run "make SOMETHING.pem".

To create a key for use with Apache, run "make genkey".
To create a CSR for use with Apache, run "make certreq".
To create a test certificate for use with Apache, run "make testcert".

To create a test certificate with serial number other than zero, add
SERIAL=num

Examples:
  make server.key
  make server.csr
  make server.crt
  make stunnel.pem
  make genkey
  make certreq
  make testcert
  make server.crt SERIAL=1
  make stunnel.pem SERIAL=2
  make testcert SERIAL=3

Dovecot requires a pem, which consists of a key and a cert. Once generated, place in the location that is outlined in the server configuration.

[root@station certs]# make dovecot.pem
umask 77 ; \
        PEM1=`/bin/mktemp /tmp/openssl.XXXXXX` ; \
        PEM2=`/bin/mktemp /tmp/openssl.XXXXXX` ; \
        /usr/bin/openssl req -utf8 -newkey rsa:1024 -keyout $PEM1 -nodes
-x509 -days 365 -out $PEM2 -set_serial 0 ; \
        cat $PEM1 >  dovecot.pem ; \
        echo ""    >> dovecot.pem ; \
        cat $PEM2 >> dovecot.pem ; \
        rm -f $PEM1 $PEM2
Generating a 1024 bit RSA private key
.............++++++
..++++++
writing new private key to '/tmp/openssl.B21904'
You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter ’.’, the field will be left blank.
Country Name (2 letter code) [GB]:US
State or Province Name (full name) [Berkshire]:Texas
Locality Name (eg, city) [Newbury]:San Antonio
Organization Name (eg, company) [My Company Ltd]: SSL example 
Organizational Unit Name (eg, section) []:3rd shift
Common Name (eg, your name or your server's hostname)
[]:station.rhce.example.com
Email Address []:user@rhce.example.com
[root@station certs]# ls
ca-bundle.crt  dovecot.pem  localhost.crt  make-dummy-cert  Makefile
mailtips for checking email during the test utilize mutt
mutt -s imaps://user@@serverhost
mutt -f imaps://localhost for checking/displaying:

q:Exit  ?:Help
This certificate belongs to:
   station.rhce.example.com
   Unknown
   SSL example
   3rd shift
   San Antonio

This certificate was issued by:
   station.rhce.example.com
   Unknown
   SSL example
   3rd shift
   San Antonio

This certificate is valid
   from Aug  9 16:52:18 2008 GMT
     to Aug  8 16:52:18 2009 GMT

Fingerprint: B247 62D4 197F 401B 61EA BC83 8733 8D9A
Telnet test to port 110 and SSL mutt foo.
[root@station etc]# telnet 0 110
Trying 0.0.0.0...
Connected to 0 (0.0.0.0).
Escape character is '^]'.
+OK Dovecot ready.
user mike
+OK
pass redhat
+OK Logged in.
list
+OK 1 messages:
1 472
.
retr 472
-ERR There's no message 472.
retr 1
+OK 472 octets
Return-Path: <root@station.example.com>
X-Original-To: ru@station.example.com
Delivered-To: user@station.example.com
Received: by station.example.com (Postfix, from userid 0)
        id CFB341988BE; Thu,  9 Aug 2007 13:09:10 -0500 (CDT)
To: ru@station.example.com
Subject: maildirdelivery
Message-Id: <20070809180910.CFB341988BE@station13.example.com>
Date: Thu,  9 Aug 2007 13:09:10 -0500 (CDT)
From: root@station.example.com (root)
maildir lab example

additional notes post lab

edits to /etc/dovecot.conf

protocols = imap imaps pop3 pop3s

the pem copied into these locations
##
## SSL settings
##

# IP or host address where to listen in for SSL connections. Defaults
# to above if not specified.
#ssl_listen =

# Disable SSL/TLS support.
ssl_disable = no

# PEM encoded X.509 SSL/TLS certificate and private key. They're opened
before
# dropping root privileges, so keep the key file unreadable by anyone but
# root. Included doc/mkcert.sh can be used to easily generate self-signed
# certificate, just make sure to update the domains in dovecot-openssl.cnf
ssl_cert_file = /etc/pki/dovecot/certs/dovecot.pem
ssl_key_file = /etc/pki/dovecot/private/dovecot.pem

Older posts: 1 2 3 ... 13