Webmail with SSL Certificates

This stack is part of a larger project that I created nearly ten years ago. I am on the fourth rewrite of this for some internal email. We are in the process of migrating from Cyrus and Squirrelmail to Dovecot and RoundCube. These are my notes from that build process.

Stack:
Postfix
Dovecot
Apache
RoundCube
Maria DB

We run an ASA at the Circus, so we turn off the firewalls internally.

systemctl disable firewalld
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
Removed symlink /etc/systemd/system/basic.target.wants/firewalld.service.
systemctl stop firewalld

Enable optional packages for RHEL.

subscription-manager repos --enable=rhel-7-server-optional-rpms
yum update

Install and start Maria DB.

yum install mariadb mariadb-server
systemctl enable mariadb
systemctl start mariadb
mysql_secure_installation

Apache install and start.

yum install httpd httpd-devel php mod_ssl
systemctl enable httpd
systemctl start httpd

Dovecot install and start.

yum install dovecot dovecot-mysql
systemctl enable dovecot
systemctl start dovecot

First we have to extract the private key from the .pfx file for use with Postfix, Apache and Dovecot. I am using an IIS key from GoDaddy to start.

Split out the private key.

openssl pkcs12 -in CircusStar.pfx -nocerts -out circusprivate-withpassword.pem

Split out the public key.

openssl pkcs12 -in CircusStar.pfx -clcerts -nokeys -out circuspublic.pem

Split out the private key without password.

openssl rsa -in circusprivate-withpassword.pem -out circusprivate-wopassword.pem

These keys will be put in the following locations for each application.

Apache
SSLCertificateFile “/etc/ssl/certs/circuspublic.pem”
SSLCertificateKeyFile “/etc/ssl/certs/circusprivate-wopassword.pem”

Postfix
SSLCertificateFile “/etc/ssl/certs/circuspublic.pem”
SSLCertificateKeyFile “/etc/ssl/certs/circusprivate-wopassword.pem”

DoveCot
ssl_cert = </etc/ssl/certs/circuspublic.pem
ssl_key = </etc/ssl/certs/circusprivate-wopassword.pem

Start on the Maria installation.

 mysql_secure_installation 

Now add a database, tables and users.

 
cat mariadb.create.virtual.tables CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mailserver` /*!40100 DEFAULT CHARACTER SET latin1 */; USE `mailserver`; CREATE USER 'mailuser'@'127.0.0.1' IDENTIFIED BY 'CHANGEME'; GRANT ALL PRIVILEGES ON mailserver.* TO 'mailuser'@'127.0.0.1'; CREATE TABLE `virtual_domains` (   `id` int(11) NOT NULL auto_increment,   `name` varchar(50) NOT NULL,   PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `virtual_users` (   `id` int(11) NOT NULL auto_increment,   `domain_id` int(11) NOT NULL,   `password` varchar(106) NOT NULL,   `email` varchar(100) NOT NULL,   PRIMARY KEY (`id`),   UNIQUE KEY `email` (`email`),   FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `virtual_aliases` (   `id` int(11) NOT NULL auto_increment,   `domain_id` int(11) NOT NULL,   `source` varchar(100) NOT NULL,   `destination` varchar(100) NOT NULL,   PRIMARY KEY (`id`),   FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `mailserver`.`virtual_domains`   (`id` ,`name`) VALUES   ('1', 'securemail.chainringcircus.org'),   ('2', 'securemail4.chainringcircus.org'); INSERT INTO `mailserver`.`virtual_users`   (`id`, `domain_id`, `password` , `email`) VALUES   ('1', '1', ENCRYPT('CHANGEME', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'judson.bishop.gmail.com@securemail.chainringcircus.org'),   ('1', '1', ENCRYPT('CHANGEME', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'test.em@securemail4.chainringcircus.org'); CREATE DATABASE roundcubemail; GRANT ALL PRIVILEGES ON roundcubemail.* TO mail@localhost IDENTIFIED BY 'CHANGEME'; FLUSH PRIVILEGES; 

Check to make sure everything worked.

 
mysql -u root -p mailserver Enter password: 
MariaDB [mailserver]> select * from virtual_domains;
+----+---------------------------------+
| id | name                            |
+----+---------------------------------+
|  1 | securemail.chainringcircus.org  |
|  2 | securemail4.chainringcircus.org |
+----+---------------------------------+
2 rows in set (0.01 sec)

And check the users.

MariaDB [mailserver]> select * from virtual_users;

The password is going to be a long jumble that doesn't translate well to a blog. This query will omit the password field.

MariaDB [mailserver]> select id, domain_id, email from virtual_users;
+----+-----------+--------------------------------------------------------+
| id | domain_id | email                                                  |
+----+-----------+--------------------------------------------------------+
|  1 |         1 | judson.bishop.gmail.com@securemail.chainringcircus.org |
|  2 |         2 | test.me@securemail4.chainringcircus.org                |
+----+-----------+--------------------------------------------------------+

Make the directories for the two domains.

mkdir -p /var/mail/vhosts/securemail.chaincircus.org
mkdir -p /var/mail/vhosts/securemail4.chaincircus.org

Postfix is next in the stack. Here is the /etc/postfix/main.cf file.

cat /etc/postfix/main.cf | egrep -v "#|^$"
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
mail_owner = postfix
myhostname = securemail4.chainringcircus.org
inet_interfaces = all
inet_protocols = all
mydestination =
unknown_local_recipient_reject_code = 550
mynetworks = 192.168.10.0/24
relayhost = [192.168.10.193]
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
home_mailbox = Maildir/
debug_peer_level = 2
debugger_command =
	 PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
	 ddd $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/sbin/sendmail.postfix
newaliases_path = /usr/bin/newaliases.postfix
mailq_path = /usr/bin/mailq.postfix
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/share/man
smtp_sasl_type = dovecot
smtp_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain =
helpful_warnings = yes
transport_maps = hash:/etc/postfix/transport
helpful_warnings = yes
default_destination_concurrency_limit = 3
message_size_limit = 20480000
smtpd_tls_cert_file = /etc/ssl/certs/circuspublic.pem
smtpd_tls_key_file = /etc/ssl/certs/circusprivate-wopassword.pem
smtpd_use_tls = yes
smtp_tls_loglevel = 3
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf, mysql:/etc/postfix/mysql-virtual-email2email.cf
virtual_mailbox_base = /var/mail/vhosts

This is how to enable TLS on Postfix.

smtpd_tls_cert_file = /etc/ssl/certs/circuspublic.pem
smtpd_tls_key_file = /etc/ssl/certs/circusprivate-wopassword.pem
smtpd_use_tls = yes
smtp_tls_loglevel = 3
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom

Set up the /etc/postfix/master.cf file. Make sure you have smtps and Dovecot set up.

smtps     inet  n       -       n       -       -       smtpd
  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o milter_macro_daemon_name=ORIGINATING

Further down add Dovecot.

# DOVECOT
dovecot   unix  -       n       n       -       -       pipe
    flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}

After restarting, test that we have TLS in the preamble.

telnet 127.0.0.1 25
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
220 securemail4.chainringcircus.org ESMTP Postfix
ehlo test.org
250-securemail4.chainringcircus.org
250-PIPELINING
250-SIZE 20480000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN

Check if Postfix is listening on 465.

ss -tnpl | grep 465
LISTEN     0      100          *:465                      *:*                   users:(("master",pid=17282,fd=22))
LISTEN     0      100         :::465                     :::*                   users:(("master",pid=17282,fd=23))

Now test port 465.

openssl s_client -connect 127.0.0.1:465
CONNECTED(00000003)
depth=0 OU = Domain Control Validated, CN = *.chainringcircus.org
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 OU = Domain Control Validated, CN = *.chainringcircus.org
verify error:num=27:certificate not trusted
verify return:1
depth=0 OU = Domain Control Validated, CN = *.chainringcircus.org
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:/OU=Domain Control Validated/CN=*.chainringcircus.org
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFGjCCBAKgAwIBAgIJAIxTKDDCrcdfMA0GCSqGSIb3DQEBCwUAMIG0MQswCQYD
VQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEa
MBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4xLTArBgNVBAsTJGh0dHA6Ly9jZXJ0
cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzEzMDEGA1UEAxMqR28gRGFkZHkgU2Vj
dXJlIENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTE1MDgyNDE0NDIzOVoX
DTE4MDkwNzE0NTQzOVowODEhMB8GA1UECxMYRG9tYWluIENvbnRyb2wgVmFsaWRh
dGVkMRMwEQYDVQQDDAoqLmVhbWMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAkkXlK1db90Sb9A6mtUoGmeog06Sy8HjqVjVnAWw/KWFMjWAKyOHX
yvxtLqQWGPZ6i6Px+bZ2PK1qKalt/5bWHv7RQv53mWS+oktUcP/LC4tX39G5C9/N
KBfZUf5/sKcI7urXbAqwW5h3R50GahymBYJ2TXYN1Os6+otSzCQ9PrXKy9HN4Nqg
HCmavGDwxGi6dB9j606Xrf0lk7ZrMSSNPQFQdgKG1JGJplFt04FsfVnRsmDo+17G
i5ecT2H5mNMFX1Im0b8A/b81EUO5RXnrzuKBIdyvCBnwynPsE61zimGSAa6StZbC
AOZHtWocH/LKsGXHmeFrEtTc3CNkqThgLwIDAQABo4IBqDCCAaQwDAYDVR0TAQH/
BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDgYDVR0PAQH/BAQD
AgWgMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Rp
ZzJzMS0xMTIuY3JsMFMGA1UdIARMMEowSAYLYIZIAYb9bQEHFwEwOTA3BggrBgEF
BQcCARYraHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5
LzB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmdvZGFk
ZHkuY29tLzBABggrBgEFBQcwAoY0aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5
LmNvbS9yZXBvc2l0b3J5L2dkaWcyLmNydDAfBgNVHSMEGDAWgBRAwr0njsw0gzCi
M9f7bLPwtCyAzjAfBgNVHREEGDAWggoqLmVhbWMub3JngghlYW1jLm9yZzAdBgNV
HQ4EFgQUIY0IX76FbTAW+vVmjvDyLIu3alMwDQYJKoZIhvcNAQELBQADggEBAAaY
t2a10js8OvkVjULDlQH4JGHj+6gf8yu+FfSH1dTVWxzqhLr8jPJGPG6Ib81fParj
nKh9lVDbuaKELerSt+i7v9E7YAjPc23gx8oAv0vOg9OjutKWbDMrkdSCN9NEdSzU
HB0G4145HmT6Ca/YO9PFwF5VC7WYlJu3wxoW3K/b1LMVs7xN3Hn2MqKc5KsDTkKD
+e2wN2eFP1uDetZC46Bc9lqEOaV00Ti0MjMlmBMnqX2JbDp09IVB6Gd/bIR7YhHA
lOTQYw/NZBf2AOOKpryBly+otv8mK3eHjhKdenT8O88xZpypYvIPhUSDx3SCy0Qb
n6/B2kZI6ZtQlBZqnBY=
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/CN=*.chainringcircus.org
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
---
No client certificate CA names sent
Server Temp Key: ECDH, prime256v1, 256 bits
---
SSL handshake has read 1969 bytes and written 373 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: DD3ABB7ABA5E19C9381B356E8E2745ECA9C1E86D59AE46D98F3683707F468B43
    Session-ID-ctx:
    Master-Key: 66F6CBBAE1093686C47C222D9DFFD5D14A8ECC749F61947A7E36FB65B59941A424C48CF23ED93EC19AB492C20D2FF1E7
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    TLS session ticket lifetime hint: 3600 (seconds)
    TLS session ticket:
    0000 - 1b f3 d3 ab 24 9a 4e 81-16 3b ef 64 93 e1 50 7d   ....$.N..;.d..P}
    0010 - db 51 bf ef 14 ee 3c 59-0f a3 2c 4c 4a 41 5b 58   .Q....<Y..,LJA[X
    0020 - 37 d8 ab 7e 43 64 3c 54-31 fb 27 07 16 b5 78 0a   7..~Cd<T1.'...x.
    0030 - 70 ed 90 34 b2 7f 4a 76-8c 43 ea 54 a0 d0 e6 5d   p..4..Jv.C.T...]
    0040 - 51 c7 e3 3c f9 be ef d6-61 e6 23 31 61 f8 c3 14   Q..<....a.#1a...
    0050 - fe 8d 25 04 03 b0 1d 31-11 aa 35 a3 3a 1b 64 d2   ..%....1..5.:.d.
    0060 - 97 32 50 68 c5 77 ac 67-6f 4b 7a 8d be 03 0c 39   .2Ph.w.goKz....9
    0070 - 9f b1 1d 46 70 f0 36 4f-55 b8 48 9b 36 ff 92 b6   ...Fp.6OU.H.6...
    0080 - e0 64 81 92 55 46 db 76-60 f3 55 6a 30 79 a5 89   .d..UF.v`.Uj0y..
    0090 - 3b af 02 9c 7b 2e 12 1e-45 eb 2c 9a fa 62 bb a2   ;...{...E.,..b..

    Start Time: 1489503195
    Timeout   : 300 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---
220 securemail.chainringcircus.org ESMTP Postfix

Now test the SQL integration with Postfix.

postmap -q securemail.chainringcircus.org mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
1

postmap -q securemail.chainringcircus.org mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
1

postmap -q test.me@securemail.chainringcircus.org mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
1

postmap -q judson.bishop.gmail.com@securemail.chainringcircus.org mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
1

Dovecot Configuration
Add the vmail user.

groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /var/mail

Change ownership.

chown -R vmail:vmail /var/mail/
chown -R vmail:dovecot /etc/dovecot


Configure the file /etc/dovecot/dovecot.conf.

cat dovecot.conf | egrep -v "#|^$"
protocols = imap pop3 lmtp
!include conf.d/10-auth.conf
!include conf.d/10-ssl.conf
!include conf.d/10-logging.conf
!include conf.d/10-mail.conf
!include conf.d/10-master.conf

This leads to a chain of includes, the first of which is /etc/dovecot/conf.d/10-auth.conf.

cat /etc/dovecot/conf.d/10-auth.conf | egrep -v "#|^$"
disable_plaintext_auth = yes
auth_mechanisms = plain login
!include auth-sql.conf.ext

The end of this include is /etc/dovecot/conf.d/auth-sql.conf.ext. This sets up the MySQL configuration.

cat conf.d/auth-sql.conf.ext | egrep -v "#|^$"
passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
  driver = static
  args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}

And finally the arguments for the MySQL query.

cat dovecot-sql.conf.ext | egrep -v "#|^$"
driver = mysql
connect = host=127.0.0.1 dbname=mailserver user=mailuser password=CHANGEME
default_pass_scheme = SHA512-CRYPT
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';

The file /etc/dovecot/conf.d/10-ssl.conf.

cat /etc/dovecot/conf.d/10-ssl.conf | egrep -v "#|^$"
ssl_cert = </etc/ssl/certs/circuspublic.pem
ssl_key = </etc/ssl/certs/circusprivate-wopassword.pem

In order to figure everything out, I used this file quite a bit. If needed, just read the comments.

cat /etc/dovecot/conf.d/10-logging.conf | egrep -v "#|^$"
log_path = syslog

This is important as it has to match your setup for Postfix.

# cat /etc/dovecot/conf.d/10-mail.conf | egrep -v "#|^$"
mail_location = maildir:/var/mail/vhosts/%d/%n
mail_home = /var/mail/vhosts/%d/%n
namespace inbox {
  inbox = yes
}
mail_privileged_group = mail
first_valid_uid = 1000
mbox_write_locks = fcntl


Finally this controls what services are started.
cat /etc/dovecot/conf.d/10-master.conf | egrep -v "#|^$"
service imap-login {
  inet_listener imap {
  }
  inet_listener imaps {
    port = 993
    ssl = yes
  }
}
service pop3-login {
  inet_listener pop3 {
  }
  inet_listener pop3s {
    port = 995
    ssl = yes
  }
}
service lmtp {
   unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
   }
}
service imap {
}
service pop3 {
}
service auth {
  unix_listener /var/spool/postfix/private/auth {
	mode = 0666
	user = postfix
	group = postfix
  }
  unix_listener auth-userdb {
	mode = 0600
	user = vmail
  }
  user = dovecot
}
service auth-worker {
}
service dict {
  unix_listener dict {
  }
}

Test that the user works.

doveadm user test.me@securemail4.chainringcircus.org
field	value
uid	5000
gid	5000
home	/var/mail/vhosts/securemail4.chainringcircus.org/test.me
mail	maildir:/var/mail/vhosts/securemail4.chainringcircus.org/test.me


Test the install.  I am only going to output the certificate once at the bottom, so that you get the idea, otherwise, it's just too much text.

openssl s_client -connect 127.0.0.1:imaps
telnet 127.0.0.1 imap
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE STARTTLS AUTH=PLAIN AUTH=LOGIN] Dovecot ready.

Test that POP3S works.

openssl s_client -connect 127.0.0.1:pop3s

Check IMAPS.

openssl s_client -connect 127.0.0.1:imaps
CONNECTED(00000003)
depth=0 OU = Domain Control Validated, CN = *.chainringcircus.org
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 OU = Domain Control Validated, CN = *.chainringcircus.org
verify error:num=27:certificate not trusted
verify return:1
depth=0 OU = Domain Control Validated, CN = *.chainringcircus.org
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:/OU=Domain Control Validated/CN=*.chainringcircus.org
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFGjCCBAKgAwIBAgIJAIxTKDDCrcdfMA0GCSqGSIb3DQEBCwUAMIG0MQswCQYD
VQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEa
MBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4xLTArBgNVBAsTJGh0dHA6Ly9jZXJ0
cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzEzMDEGA1UEAxMqR28gRGFkZHkgU2Vj
dXJlIENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTE1MDgyNDE0NDIzOVoX
DTE4MDkwNzE0NTQzOVowODEhMB8GA1UECxMYRG9tYWluIENvbnRyb2wgVmFsaWRh
dGVkMRMwEQYDVQQDDAoqLmVhbWMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAkkXlK1db90Sb9A6mtUoGmeog06Sy8HjqVjVnAWw/KWFMjWAKyOHX
yvxtLqQWGPZ6i6Px+bZ2PK1qKalt/5bWHv7RQv53mWS+oktUcP/LC4tX39G5C9/N
KBfZUf5/sKcI7urXbAqwW5h3R50GahymBYJ2TXYN1Os6+otSzCQ9PrXKy9HN4Nqg
HCmavGDwxGi6dB9j606Xrf0lk7ZrMSSNPQFQdgKG1JGJplFt04FsfVnRsmDo+17G
i5ecT2H5mNMFX1Im0b8A/b81EUO5RXnrzuKBIdyvCBnwynPsE61zimGSAa6StZbC
AOZHtWocH/LKsGXHmeFrEtTc3CNkqThgLwIDAQABo4IBqDCCAaQwDAYDVR0TAQH/
BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDgYDVR0PAQH/BAQD
AgWgMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Rp
ZzJzMS0xMTIuY3JsMFMGA1UdIARMMEowSAYLYIZIAYb9bQEHFwEwOTA3BggrBgEF
BQcCARYraHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5
LzB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmdvZGFk
ZHkuY29tLzBABggrBgEFBQcwAoY0aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5
LmNvbS9yZXBvc2l0b3J5L2dkaWcyLmNydDAfBgNVHSMEGDAWgBRAwr0njsw0gzCi
M9f7bLPwtCyAzjAfBgNVHREEGDAWggoqLmVhbWMub3JngghlYW1jLm9yZzAdBgNV
HQ4EFgQUIY0IX76FbTAW+vVmjvDyLIu3alMwDQYJKoZIhvcNAQELBQADggEBAAaY
t2a10js8OvkVjULDlQH4JGHj+6gf8yu+FfSH1dTVWxzqhLr8jPJGPG6Ib81fParj
nKh9lVDbuaKELerSt+i7v9E7YAjPc23gx8oAv0vOg9OjutKWbDMrkdSCN9NEdSzU
HB0G4145HmT6Ca/YO9PFwF5VC7WYlJu3wxoW3K/b1LMVs7xN3Hn2MqKc5KsDTkKD
+e2wN2eFP1uDetZC46Bc9lqEOaV00Ti0MjMlmBMnqX2JbDp09IVB6Gd/bIR7YhHA
lOTQYw/NZBf2AOOKpryBly+otv8mK3eHjhKdenT8O88xZpypYvIPhUSDx3SCy0Qb
n6/B2kZI6ZtQlBZqnBY=
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/CN=*.chainringcircus.org
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
---
No client certificate CA names sent
Server Temp Key: ECDH, secp384r1, 384 bits
---
SSL handshake has read 2001 bytes and written 405 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: A75756A316C964086D57EC8F3858BF4280CDDBB20426F1B0FCEDEDEDD14F8F62
    Session-ID-ctx:
    Master-Key: 4D2C108B898241C2F6D740946FDFF7F20397B852750B5C8999441B0A967537431D2C6465FA628944FACA504A173F45A2
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - f7 de 20 41 d4 27 18 1c-99 a6 4e e6 e9 5c 92 cf   .. A.'....N..\..
    0010 - bb 00 40 23 04 fd 38 74-93 64 17 d2 9d e8 7d 9c   ..@#..8t.d....}.
    0020 - d2 7c 70 26 59 2e bf ec-44 30 c3 de 67 95 d2 c4   .|p&Y...D0..g...
    0030 - 50 58 49 e7 55 4b 1f de-1a 97 1d 10 bb a3 f4 ad   PXI.UK..........
    0040 - 15 8b ef cd 2f c7 3a 47-e9 a0 45 66 1a 60 54 e7   ..../.:G..Ef.`T.
    0050 - 7f 92 1a 47 53 0b 39 b2-6e fb cb 78 ab 98 be dd   ...GS.9.n..x....
    0060 - 01 c9 a1 04 fd 8d b7 98-ae 1b a8 c2 1e b1 46 cc   ..............F.
    0070 - e7 dc de 8f 1f e8 1a 73-8f a2 70 39 6a c6 f5 03   .......s..p9j...
    0080 - a7 a8 99 8b 9e c2 81 3a-83 25 12 33 5e 0d ff 38   .......:.%.3^..8
    0090 - ba 5b 8a d2 13 80 17 4b-5d b2 c1 52 32 66 2f 41   .[.....K]..R2f/A

    Start Time: 1488919043
    Timeout   : 300 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN] Dovecot ready.

This bit me and took me a couple of hours to find it. Go ahead and check this.

postconf | grep dovecot-lmtp
virtual_transport = lmtp:unix:private/dovecot-lmtp

doveconf  | grep dovecot-lmtp
  unix_listener /var/spool/postfix/private/dovecot-lmtp {

 

At this point I installed Thunderbird and tested sending and receiving email.

Screen Shot 2017-03-14 at 10.53.27 AM

Enable SSL for Apache.
First go through and remove all of the Listen directives in the Apache configuration files. If you don't it will come back to bite you.

grep -ir Listen /etc/httpd
/etc/httpd/conf/httpd.conf:# Listen: Allows you to bind Apache to specific IP addresses and/or
/etc/httpd/conf/httpd.conf:# Change this to Listen on specific IP addresses as shown below to
/etc/httpd/conf/httpd.conf:#Listen 12.34.56.78:80
/etc/httpd/conf/httpd.conf:#Listen 80
/etc/httpd/conf.d/securemail.conf:Listen 192.168.1.1:443
/etc/httpd/conf.d/ssl.conf:# When we also provide SSL we have to listen to the
/etc/httpd/conf.d/ssl.conf:#Listen 12.34.56.78:443 https

The only thing I changed in the main httpd.conf is I commented out the Listen directives for port 80 and changed the DocumentRoot, however, we just want to make sure that we have Apache up and running with SSL. We will get to that in the RoundCube later. From /etc/httpd/httpd.conf.

 
DocumentRoot "/var/www/html/roundcubemail-1.2.3"
#Listen 12.34.56.78:80
#Listen 80

Next I commented out all the SSL certificate stuff in /etc/httpd/conf.d/ssl.conf.

cat ssl.conf | grep SSLC
# Use "SSLCryptoDevice" to enable any supported hardware
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!SEED:!IDEA
#SSLCipherSuite RC4-SHA:AES128-SHA:HIGH:MEDIUM:!aNULL:!MD5
#SSLCertificateFile /etc/pki/tls/certs/localhost.crt
#SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt

Set up the securemail virtual host with SSL certificates you created for Dovecot.

cat /etc/httpd/conf.d/securemail.conf
LoadModule ssl_module modules/mod_ssl.so

Listen 172.22.226.218:443
<VirtualHost *:443>
    ServerName securemail4.chainringcircus.org
    SSLEngine on
    SSLCertificateFile "/etc/ssl/certs/circuspublic.pem"
    SSLCertificateKeyFile "/etc/ssl/certs/circusprivate-wopassword.pem"
</VirtualHost>

Restart Apache

systemctl restart httpd

Browse to the web server, https://securemail.chainringcircus.org.

Screen Shot 2017-03-07 at 10.13.35 AM

Install RoundCube.
First set the timezone for PHP in /etc/php.ini, the list is here.

date.timezone = America/Chicago

Create the database for RoundCube.

mysql -u root -p <mariadb.create.roundcube
Enter password:
cat mariadb.create.roundcube
CREATE DATABASE roundcubemail;
GRANT ALL PRIVILEGES ON roundcubemail.* TO mail@localhost IDENTIFIED BY 'CHANGEME';
FLUSH PRIVILEGES;

Start the RoundCube install.

mv roundcubemail-1.2.3-complete.tar.gz /var/www/html/
cd /var/www/html/
tar -xvzf roundcubemail-1.2.3-complete.tar.gz

Browse to the configuration web site.

https://securemail.chainringcircus.org/roundcubemail-1.2.3/installer/

In order to clean up a number of missing modules and extensions. If you do not have all of these RPMs, please see one of the first steps above to enable optional packages for RHEL.

yum install -y php-xml php-mysql php-pdo php-mbstring php-intl php-ldap
systemctl restart httpd

Screen Shot 2017-03-07 at 11.21.56 AM

SecureMail
Edit the file /etc/postfix/master.cf

filter    unix  -       n       n       -       10      pipe
    flags=Rq user=filter argv=/usr/local/bin/secure-parse.multiple -f ${sender} -- ${recipient}

Sources.
http://linux.m2osw.com/setting-postfixcourier-godaddy-ssl-certificate

https://www.godaddy.com/help/apache-install-a-certificate-centos-5238

https://www.rosehosting.com/blog/set-up-ssl-encrypted-connection-in-postfix-dovecot-and-apache/

https://github.com/roundcube/roundcubemail/wiki/Installation

http://www.tecmint.com/create-apache-https-self-signed-certificate-using-nss/

http://www.tecmint.com/setup-postfix-mail-server-and-dovecot-with-mariadb-in-centos/

http://www.tecmint.com/install-and-configure-roundcube-webmail-for-postfix-mail-server/

http://wiki.dovecot.org/TestInstallation

https://www.markbrilman.nl/2011/08/howto-convert-a-pfx-to-a-seperate-key-crt-file/

https://www.linode.com/docs/email/postfix/email-with-postfix-dovecot-and-mariadb-on-centos-7

https://sycure.wordpress.com/2008/05/15/tips-using-openssl-to-extract-private-key-pem-file-from-pfx-personal-information-exchange/

http://www.tecmint.com/setup-postfix-mail-server-and-dovecot-with-mariadb-in-centos/

https://debian-administration.org/article/275/Setting_up_an_IMAP_server_with_dovecot

http://www.postfix.org/TLS_README.html

https://www.linode.com/docs/email/postfix/email-with-postfix-dovecot-and-mysql

Posted in Uncategorized | Leave a comment

Linux NAT with a Web Interface

In 2006 I wrote a web interface for Linux NAT tables. It was not pretty, but it moved NAT from the core routers or firewalls onto a server that the PC Techs could manage. The goal was to push management of creating printer NAT translations from the Senior team to the team that adds and removes the physical printers.

As of last weekend that server is finally out of service and I have been able to write up a howto and offer the code. At it’s peak we had nearly 1,000 hosts and printers combined being NATed.

When I initially wrote it, it was on two physical servers.  During one upgrade we moved it to a single virtual machine where it has run for the past six years.  I upgraded it a couple of times, but I think it’s pretty a good project to have run all of the printing in a hospital for eleven years.  At one point there was a bug in the code that allowed PC techs to create duplicate NATs.  This only became a problem when the server was rebooted.  I found that bug and fixed it shortly after.

I used Ubuntu Linux, and this is the what the /etc/network/interfaces looked like. Notice that #translate 0.0.0.0 line. This tells the scripts that there is no translate to be created, while a line #translate 192.168.1.1 tells the scripts to translate the real address to 192.168.1.1. In this manner, the /etc/network/inerfaces becomes the flat file that creates all of the NATs.

root@translate2:/var/www# cat /etc/network/interfaces
auto lo
iface lo inet loopback

#translate 0.0.0.0
auto eth0
iface eth0 inet static
address 172.22.25.194
netmask 255.255.252.0
#gateway 172.22.24.1

#translate 0.0.0.0
auto eth1
iface eth1 inet static
address 172.22.100.58
netmask 255.255.255.0
gateway 172.22.100.1

#translate 172.22.71.239
auto eth0:4
iface eth0:4 inet static
address 172.22.25.160
netmask 255.255.252.0

In order to allow the PC Techs to make the changes, I modified suidcgi.c from Sverre Huseby. Below is what I added to the suidcgi.c comments.

/**************************************************************************
 *
 *  FILE            suidcgi.c
 *  MODULE OF       suidcgi - a set UID wrapper for CGI scripts.
 *
 *  DESCRIPTION     This is a setuid wrapper, intended to run CGI scripts
 *                  accessed from the World Wide Web. The script will be
 *                  run as the user owning it, giving access to files
 *                  without making them readable and writable to all.
 *
 *  WRITTEN BY      Sverre H. Huseby <sverrehu@online.no>
 *  HACKED BY	    Jud Bishop <judson.bishop@gmail.com>
 *  			My hack has removed most of the sanity checking put
 *  			in by Sverre.  I need to manipulate iptables and
 *  			interfaces from the web and kept getting caught by
 *  			different sanity checks.  I'm sure for good reason 🙂
 *
 *  			So the point of this paragraph is this, this script
 *  			is insecure on so many levels that you should not use
 *  			it!
 *
 **************************************************************************/

In order to make the cgi set uid of root, you have to create a symlink from the .cgi to the program suidcgi.

root@translate2:/var/www/cgi-bin# ls -alh
total 96K
drwxr-xr-x 3 root root     4.0K 2015-04-30 13:57 .
drwxr-xr-x 5 root root     4.0K 2006-10-25 12:06 ..
-rwxr-xr-x 1 root root     3.5K 2006-10-30 05:54 confirm.pl
lrwxrwxrwx 1 root root        7 2013-02-12 14:05 delete_files.cgi -> suidcgi
-rwxr-xr-x 1 root root     5.6K 2012-05-10 07:33 delete_files.pl
-rwxr-xr-x 1 root root     3.6K 2009-01-09 10:56 delete.pl
lrwxrwxrwx 1 root root        7 2013-02-12 14:05 ifconfig.cgi -> suidcgi
-rwxr-xr-x 1 root root      280 2006-10-25 12:07 ifconfig.sh
lrwxrwxrwx 1 root root        7 2013-02-12 14:05 interface.cgi -> suidcgi
-rwxr-xr-x 1 root root     6.8K 2009-04-29 09:02 interface.pl
-rw-r--r-- 1 root www-data  35K 2017-01-03 08:18 iptables
lrwxrwxrwx 1 root root        7 2013-02-12 14:05 iptables.cgi -> suidcgi
-rwxr-xr-x 1 root root      322 2006-10-25 15:00 iptables.sh
lrwxrwxrwx 1 root root        7 2013-02-12 14:05 list.cgi -> suidcgi
-rwxr-xr-x 1 root root     3.5K 2006-10-30 08:08 list.pl
drwxr-xr-x 2 root root     4.0K 2013-11-21 11:01 old
-rwxr-xr-x 1 root root      288 2006-10-25 12:07 printenv
-rwsr-xr-x 1 root root     6.0K 2006-10-25 12:07 suidcgi

Here is a listing of the default web server directory.

root@translate2:/var/www/html# ls /var/www/html/ -alh
total 20K
drwxr-xr-x 2 root root 4.0K 2009-01-12 12:42 .
drwxr-xr-x 5 root root 4.0K 2006-10-25 12:06 ..
-rw-r--r-- 1 www-data www-data  284 2006-11-06 13:38 index.html
-rwxr-xr-x 1 www-data www-data 1.5K 2006-10-25 12:07 interface.html

When the server starts, it reads the /etc/rc.local script, which calls the rc.local.firewall script. This script reads the /etc/network/interfaces file and builds the iptables rules.

cat rc.local.firewall
#!/usr/bin/perl

# 2006-11-06
# Jud Bishop

# flush the default filter rule
system "iptables --flush";

# flush the nat filter
system "iptables --table nat --flush";

# delete all of the other chains
system "iptables --delete-chain";
system "iptables --table nat --delete-chain";

# Read the file into an array
open (FILE,"</etc/network/interfaces") or die "Error: can't open file /etc/network/interfaces\n $!";
        # put the file into the array
        @array = <FILE>;
close FILE or die "Error: can't close $file\n $!";

# Take all of the new lines off of the array.
foreach $j ( 0 .. $#array )
{
        chomp @array[$j];
}

foreach $j ( 0 .. $#array )
{
        if ( @array[$j] =~ /^#translate/ )
        {
                ($na, $translate) = split /\ /, @array[$j];

        } elsif (  @array[$j] =~ /^address/ ) {
                ($na, $cerner) = split /\ /, @array[$j];

                if ( $translate !~ /^0/ )
                {
			system "iptables -t nat -A PREROUTING --destination $cerner -j DNAT --to $translate";
                }
        }
}

# make the source look like the translate box
system "iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to 172.22.100.58";

# enable ip forwarding
system "echo 1 > /proc/sys/net/ipv4/ip_forward";

#iptables -t nat -n -L >/var/www/cgi-bin/iptables

The process of creating or deleting a NAT works along these lines. A PC tech browses to the translate server and chooses an option:

screen-shot-2017-01-22-at-10-39-10-am

The simple HTML behind the index page, just chooses where to send the PC tech next.

<html>

<a href=interface.html>Add Translation</a>

<a href=../cgi-bin/delete.pl>Delete Translation</a> 

<a href=../cgi-bin/list.pl>Show Translations</a>

<a href=../cgi-bin/iptables.cgi>Show iptables</a>

<a href=../cgi-bin/ifconfig.cgi>Show interfaces</a>

</html>

Adding a translation walks the PC tech through the option to add a translation, confirm that it is correct and then creates it. Notice that I have pre-populated the form with some suggested IP address ranges to try and cut down on the number of errors.

screen-shot-2017-01-22-at-11-15-32-am

screen-shot-2017-01-22-at-11-16-04-am

 

Once the translation has been confirmed, it calls /var/www/cgi-bin/interface.pl that edits the /etc/network/interfaces file as well as add the NAT. Below is the comments section from the file. As I type this, I think about how I would have created this process differently today, however, it’s interesting to read my thoughts. This code has been in production over ten years, so one way or another it has stood the test of time.

#!/usr/bin/perl
# 2006-09-12
# Jud Bishop
#
#  I know I could be using suidperl but it has too much checking for me to be
#  able to manipulate system files.  SCARY.
#
#  I hate to think this is such a hack, but I check to make sure I get an IP
#  address coming in and I use full paths.
#
#  I also chose to turn off -T for taintedness although you see hacks left over
#  to deal with it.  When I get time I'll clean up the code.
#
#   This script reads in /etc/interfaces, finds the last interface, then adds
#   the new interface as the last one. It adds the interface to /etc/interfaces,
#   creates the interface on the fly and then adds a nat translation for it.
#   It never brings down nat, does everything on the fly.

Delete does something similar, it reads in the /etc/network/interfaces file as an array, finds the interface to delete, removes it. Then goes on toe down the interface and remove the NAT. There were no juicy comments in that file.

 

 

Posted in Code, Linux | Leave a comment

Troubleshoot MPLS Connectivity

Step 1 — IGP for MPLS cloud
Verification – You are on your own. (YOYO)

Step 2 — LDP Adjacencies
Pro Tip – Add the CE network to advertisements so that you don’t have to ping from some specific loopback address to confirm connectivity.
sh mpls interfaces ← Key command, is LDP enabled
sh mpls ldp neighbor ← Is LDP transport working ← Is the RID advertised?
sh mpls ldp bindings ← LRIB similar to routing table
sh mpls forwarding-table ← LFIB similar to CEF table ← Key command
sh ip cef
traceroute

Step 3 — MP-BGP between PEs
sh bgp vpnv4 unicast all summary ← Did the VPNv4 BGP establish?
debug bgp vpnv4 unicast updates ← Are extended communities being sent?
sh bgp vpnv4 unicast all neighbor x.x.x.x advertised-routes ← Are the VPNv4 routes being sent
clear ip bgp * [in|out]

Step 4 — Create VRFs, RDs and RTs
sh ip vrf detail ← Key command
sh ip vrf ← Was the vrf properly allocated
sh run vrf
sh ip route vrf
sh ip route vrf *
clear ip route vrf * ← Force re-import/export

Step 5 — Add VRFs to BGP
sh bgp vpnv4 unicast vrf BLUE

Step 6 — Customer to Provider IGP
Once again YOYO.
sh ip vrf int

Step 7 — Redistribute between MP-BGP and Customer
sh bgp vpnv4 unicast all
sh ip ospf database
sh ip eigrp topology
sh ip rip database

Step 8 — Verification
sh ip route
sh ip route vrf X

Random commands:
sh vrf ← Great Command
sh ip vrf
sh ip route vrf *
sh ip route vrf [vrf name]
ping vrf [vrf]
traceroute vrf [vrf]
sh ip bgp vpnv4 vrf RED 192.168.1.0/24
sh mpls ldp bindings 10.250.4.0 24
sh ip cef vrf BLUE 172.20.1.0
sh mpls forwarding-table
sh mpls ldp bindings local
sh ip bgp vpnv4 vrf RED 172.20.1.0/24
sh mpls ldp interfaces
sh mpls ldp neigh
sh bgp vpnv4 unicast all summary
debug vpnv4 unicast updates
sh ip cef vrf BLUE 155.1.10.0/24
sh bgp vpnv4 unicast all 155.1.10.0/24
sh ip bgp vpnv4 vrf EAMC

Posted in CCIE, Routing | Leave a comment

Enable Virtualization within a VM

So much of my lab is virtualized that I am continuously tweaking the networking and settings within VMware.  Most of the lab runs on VMware 5.5 so there are some manual tweaks that I have to do that are done in the GUI of 6.x.  This note is so that I don’t have to keep googling how to enable nested virtualization.

In order to expose hardware acceleration within a VMware host:

/vmfs/volumes/56f54bc4-e6a63540-8ac0-782bcb1f2794/WinGNS3 # vi WinGNS3.vmx

Add this line:

vhv.enable = "TRUE"
Posted in CCIE | Leave a comment

Finished 2010

I just finished adding the posts form 2010 with a smattering of other random posts. I am tired of the repetitive nature of adding posts and am going to get in some studying today.

Posted in Thoughts | Leave a comment

iTerm2 with VIRL

Yesterday my boss purchased VIRL for me. I run it on one of my ESXi servers and wanted to be able to maintain the environment I have gotten used to running, namely tabbed terminals in iTerm2. Easier said than done.

I used a couple of blogs to help get me going, but their scripts did not work for me, leading to this post.  I hope it will help others.

These are my settings under the Preferences pane of VM Maestro.screen-shot-2016-12-20-at-7-16-48-pm

Below is the script that finally worked for me. Please note, the delay 2 is one of the biggest changes I had to make, otherwise the script would put both telnet commands into the same tab.

-- 2016-12-20
-- Jud Bishop

on run argv
	
	-- last argument should be the window title
	set windowtitle to item (the count of argv) of argv as text
	
	-- all but last argument go into CLI parameters
	set cliargs to ""
	repeat with arg in items 1 thru -2 of argv
		set cliargs to cliargs & " " & arg as text
	end repeat
	
	delay 2
	
	tell application "iTerm"
		activate
		set the bounds of the first window to {1000, 500, 1900, 1200}
		if (count of windows) = 0 then
			set t to (create window with default profile)
		else
			set t to current window
		end if
		tell t
			create tab with default profile
			set s to current session
			tell s
				write text cliargs
				set name to windowtitle
			end tell
		end tell
	end tell
end run

Posted in Uncategorized | Leave a comment

C360 or Cisco Expert-Level Training Script

 

I’ve been using the C360 labs for training and have gotten tired of fighting with window management. At first I figured it would be good practice for the lab, but now I’m just tired of messing with windows, so I wrote a script to help alleviate my annoyance.

The server and port range for the lab you work on changes every time you run a different lab, so the script had to take that into account.  If you pay attention the ports you connect to are sequential, so just check the port and server of R1 and you have everything to you need.

At the end of the script it puts the iTerm windows in the lower right-hand corner of my left screen so I don’t have to move it by hand. 😉

Here are the pop-ups from the script:

screen-shot-2016-12-04-at-11-41-02-am

screen-shot-2016-12-04-at-11-40-51-am

 

-- 2016-12-04 
-- Jud Bishop 

set SERVER to the text returned of (display dialog ¬
	"Enter the server IP:" default answer "10.10.1.100")

set FIRSTPORT to the text returned of (display dialog ¬
	"Enter the first port:" default answer "11501")


tell application "iTerm"
	set netWindow to (create window with default profile)
	
	select first window
	
	set DEVICES to {"R1", "R2", "R3", "R4", "R5", "R6", "SW1", "SW2", "SW3", "SW4", "R7", "R8", "R9", "BB"}
	repeat with I from 1 to 14
		tell current window
			set newTab to (create tab with default profile)
			tell current session
				write text "telnet " & SERVER & " " & FIRSTPORT
				set name to item I of DEVICES
				set FIRSTPORT to FIRSTPORT + 1
			end tell
		end tell
	end repeat
	set the bounds of the first window to {1000, 500, 1900, 1200}
end tell

 

Posted in Uncategorized | Leave a comment