- Details
- Written by: andre
- Category: Uncategorised
- Hits: 11147
Create your own Certificate Authority
This how-to is based on jamielinux.com.
Attachments can be downloaded here
Steps described in this document:
- Creating a new, self-signed root CA from scratch
- Create an intermediate CA using the root CA
- Sign a server certificate
- Sign a client certificate
- Create a certificate revocation list (CRL)
- Setup an OCSP responder behind an Apache proxy
- Deploy certificates onto Apache webserver
- Perform a number of tests using a browser
Setup Root CA
The root CA certificate only to sign other certificate authority certificates.
Prepare the Root CA directory
Setup a directory where everything related to the CA is managed.
mkdir -p /root/DemoCA/root
cd /root/DemoCA/root
mkdir certs csr crl newcerts private
chmod 700 private
touch index.txt
echo 1000 > serial
wget -O openssl.cnf "https://andre.bytesare.us/ca-demo-files/root-openssl.cnf"
Self-sign the root ca certificate
Using our openssl.cnf’s [ v3_ca ]
extension:
cd /root/DemoCA/root
openssl genrsa -aes256 -out private/ca.key.pem 4096
openssl req -config openssl.cnf -key private/ca.key.pem -new -x509 -days 7300 -sha256 -extensions v3_ca -out certs/ca.cert.pem
# Subject: `C = AT, ST = Vienna, O = BytesAreUs GmbH, OU = BytesAreUs GmbH Certificate Authority, CN = BytesAreUs GmbH Root CA`
# Check:
openssl x509 -noout -text -in certs/ca.cert.pem
Setup an intermediate CA
Used for signing end-user certs.
Prepare the intermediate CA directory as below.
mkdir /root/DemoCA/intermediate-1
cd /root/DemoCA/intermediate-1
mkdir certs crl csr newcerts private
chmod 700 private
touch index.txt
touch index.txt.attr
echo 1000 > serial
echo 1000 > crlnumber
wget -O openssl.cnf "https://andre.bytesare.us/ca-demo-files/intermediate-openssl.cnf"
Add/Modify these lines to the [ server_cert ] section in /root/ca/intermediate/openssl.cnf
to specify CRL and OCSP Urls.
crlDistributionPoints = URI:http://ca-demo.bytesare.us/intermediate-1.crl.pem
authorityInfoAccess = OCSP;URI:http://ca-demo.bytesare.us/ocsp/intermediate-1
Create the intermediate certificate
Using our openssl.cnf’s [ v3_intermediate_ca ]
extension:
# Create csr:
cd /root/DemoCA/intermediate-1
openssl genrsa -aes256 -out private/intermediate-1.key.pem 4096
openssl req -config openssl.cnf -new -sha256 -key private/intermediate-1.key.pem -out csr/intermediate-1.csr.pem
# Subject: `C = AT, ST = Vienna, O = BytesAreUs GmbH, OU = BytesAreUs GmbH Certificate Authority, CN = BytesAreUs GmbH Intermediate CA 1`
# Sign csr with the root CA:
cd /root/DemoCA/root
openssl ca -config openssl.cnf -extensions v3_intermediate_ca -days 3650 -notext -md sha256 -in ../intermediate-1/csr/intermediate-1.csr.pem -out ../intermediate-1/certs/intermediate-1.cert.pem
# Check:
cd /root/DemoCA/intermediate-1
openssl x509 -noout -text -in certs/intermediate-1.cert.pem # check manually
openssl verify -CAfile ../root/certs/ca.cert.pem certs/intermediate-1.cert.pem
cat certs/intermediate-1.cert.pem ../root/certs/ca.cert.pem > certs/ca-chain.cert.pem
Create a server certificate
Using our openssl.cnf’s [ server_cert ]
extension:
cd /root/DemoCA/intermediate-1
openssl genrsa -aes256 -out private/ca-demo.bytesare.us.key.pem 2048
openssl req -config openssl.cnf -key private/ca-demo.bytesare.us.key.pem -new -sha256 -out csr/ca-demo.bytesare.us.csr.pem
# Subject: `C = AT, ST = Vienna, O = BytesAreUs GmbH, OU = Web Services, CN = ca-demo.bytesare.us`
openssl ca -config openssl.cnf -extensions server_cert -days 375 -notext -md sha256 -in csr/ca-demo.bytesare.us.csr.pem -out certs/ca-demo.bytesare.us.cert.pem
# Check:
openssl x509 -noout -text -in certs/ca-demo.bytesare.us.cert.pem
openssl verify -CAfile certs/ca-chain.cert.pem certs/ca-demo.bytesare.us.cert.pem
(Optional) Create and revoke another server certificate
For testing purposes, create a new server certificate with the same
name like the existing one. It is needed later to test the OCSP responder.
cd /root/DemoCA/intermediate-1
openssl genrsa -aes256 -out private/revoked.ca-demo.bytesare.us.key.pem 2048
openssl req -config openssl.cnf -key private/revoked.ca-demo.bytesare.us.key.pem -new -sha256 -out csr/revoked.ca-demo.bytesare.us.csr.pem
# Subject: `C = AT, ST = Vienna, O = BytesAreUs GmbH, OU = Web Services, CN = ca-demo.bytesare.us`
openssl ca -config openssl.cnf -extensions server_cert -days 375 -notext -md sha256 -in csr/revoked.ca-demo.bytesare.us.csr.pem -out certs/revoked.ca-demo.bytesare.us.cert.pem
# Check:
openssl x509 -noout -text -in certs/revoked.ca-demo.bytesare.us.cert.pem
openssl verify -CAfile certs/ca-chain.cert.pem certs/revoked.ca-demo.bytesare.us.cert.pem
Revoke the server cert:
cd /root/DemoCA/intermediate-1
openssl ca -config openssl.cnf -revoke certs/revoked.ca-demo.bytesare.us.cert.pem
Sign a client certificate
The client cert should be created in three steps without sending the key over the wire:
-
Client creates a CSR:
# mkdir /home/carl cd /home/carl openssl genrsa -out
This email address is being protected from spambots. You need JavaScript enabled to view it. 2048 openssl req -new -keyThis email address is being protected from spambots. You need JavaScript enabled to view it. -outThis email address is being protected from spambots. You need JavaScript enabled to view it. Subject: `C= AT, ST = Tirol, L = Innsbruck, CN = Carl the tester, emailAddress =This email address is being protected from spambots. You need JavaScript enabled to view it. ` cpThis email address is being protected from spambots. You need JavaScript enabled to view it. /tmp/ -
Then, client sends the CSR to the intermediate CA, who signs it.
Using our openssl.cnf’s
[ usr_cert ]
extension:cd /root/DemoCA/intermediate-1 cp /tmp/
This email address is being protected from spambots. You need JavaScript enabled to view it. csr/ openssl ca -config openssl.cnf -extensions usr_cert -notext -md sha256 -in csr/This email address is being protected from spambots. You need JavaScript enabled to view it. -out certs/This email address is being protected from spambots. You need JavaScript enabled to view it. cp certs/This email address is being protected from spambots. You need JavaScript enabled to view it. certs/ca-chain.cert.pem /tmp/ # Check: openssl verify -CAfile certs/ca-chain.cert.pem certs/This email address is being protected from spambots. You need JavaScript enabled to view it. -
CA returns certificate and chain to client
Who converts it into pkcs12 format to import it to his browser:
cd /home/carl cp /tmp/ca-chain.cert.pem /tmp/
This email address is being protected from spambots. You need JavaScript enabled to view it. . catThis email address is being protected from spambots. You need JavaScript enabled to view it. ca-chain.cert.pem >This email address is being protected from spambots. You need JavaScript enabled to view it. openssl pkcs12 -export -inkeyThis email address is being protected from spambots. You need JavaScript enabled to view it. -inThis email address is being protected from spambots. You need JavaScript enabled to view it. -outThis email address is being protected from spambots. You need JavaScript enabled to view it.
(Optional) Create and revoke another client cert
For negative testing the CRL later, sign another client cert and revoke it.
# mkdir /home/luzifer
cd /home/luzifer
openssl genrsa -out This email address is being protected from spambots. You need JavaScript enabled to view it. 2048
openssl req -new -key This email address is being protected from spambots. You need JavaScript enabled to view it. -out This email address is being protected from spambots. You need JavaScript enabled to view it.
Subject: `C= AT, ST = Tirol, L = Innsbruck, CN = Luzifer the Evil, emailAddress = This email address is being protected from spambots. You need JavaScript enabled to view it. `
cp This email address is being protected from spambots. You need JavaScript enabled to view it. /tmp/
cd /root/DemoCA/intermediate-1
cp /tmp/This email address is being protected from spambots. You need JavaScript enabled to view it. csr/
openssl ca -config openssl.cnf -extensions usr_cert -notext -md sha256 -in csr/This email address is being protected from spambots. You need JavaScript enabled to view it. -out certs/This email address is being protected from spambots. You need JavaScript enabled to view it.
cp certs/This email address is being protected from spambots. You need JavaScript enabled to view it. certs/ca-chain.cert.pem /tmp/
# Check:
openssl verify -CAfile certs/ca-chain.cert.pem certs/This email address is being protected from spambots. You need JavaScript enabled to view it.
cd /home/luzifer
cp /tmp/ca-chain.cert.pem /tmp/This email address is being protected from spambots. You need JavaScript enabled to view it. .
cat This email address is being protected from spambots. You need JavaScript enabled to view it. ca-chain.cert.pem > This email address is being protected from spambots. You need JavaScript enabled to view it.
openssl pkcs12 -export -inkey This email address is being protected from spambots. You need JavaScript enabled to view it. -in This email address is being protected from spambots. You need JavaScript enabled to view it. -out This email address is being protected from spambots. You need JavaScript enabled to view it.
Now, revoke luzifer’s certificate:
cd /root/DemoCA/intermediate-1
openssl ca -config openssl.cnf -revoke certs/This email address is being protected from spambots. You need JavaScript enabled to view it.
Create a CRL
CRL files are used to check if a certificate has been revoked (offline).
cd /root/DemoCA/intermediate-1
openssl ca -config openssl.cnf -gencrl -out crl/intermediate-1.crl.pem
# Check:
openssl crl -in crl/intermediate-1.crl.pem -text
cat certs/ca-chain.cert.pem crl/intermediate-1.crl.pem > /tmp/chain+crl.pem
openssl verify -crl_check -CAfile /tmp/chain+crl.pem certs/ca-demo.bytesare.us.cert.pem
openssl verify -crl_check -CAfile /tmp/chain+crl.pem certs/revoked.ca-demo.bytesare.us.cert.pem
Create an OCSP responder certificate
OCSP is used for online checking the revocation status of a certificate.
Create a signer certificate to sign the OCSP responses:
cd /root/DemoCA/intermediate-1
openssl genrsa -aes256 -out private/ocsp.key.pem 4096
openssl req -config openssl.cnf -new -sha256 -key private/ocsp.key.pem -out csr/ocsp.csr.pem
# Subject: `C = AT, ST = Vienna, O = BytesAreUs GmbH, OU = BytesAreUs GmbH Certificate Authority, CN = BytesAreUs OCSP Signer CA 1`
openssl ca -config openssl.cnf -extensions ocsp -days 375 -md sha256 -in csr/ocsp.csr.pem -out certs/ocsp.cert.pem
# Check:
openssl verify -CAfile certs/ca-chain.cert.pem certs/ocsp.cert.pem
openssl ocsp -url http://localhost:2560/ocsp -text -rmd sha256 -index index.txt -CA certs/ca-chain.cert.pem -rkey private/ocsp.key.pem -rsigner certs/ocsp.cert.pem -nrequest 2 | grep -e "Serial Number:" -e "Cert Status:" -e "Update:"
# (using a 2nd terminal)
cd /root/DemoCA/intermediate-1
openssl ocsp -CAfile certs/ca-chain.cert.pem -url http://localhost:2560/ocsp -issuer certs/intermediate-1.cert.pem -cert certs/ca-demo.bytesare.us.cert.pem
openssl ocsp -CAfile certs/ca-chain.cert.pem -url http://localhost:2560/ocsp -issuer certs/intermediate-1.cert.pem -cert certs/revoked.ca-demo.bytesare.us.cert.pem
Deploy and test the setup
To demonstrate the use of our CA, setup Apache with
- the server certificate
- an OCSP responder proxy for checking the server certificate
- a location that requires a client certificate
- a CRL file to check client certificates
Apache Configuration
Copy certificate material to a directory that apache user can access.
cd /root/DemoCA/intermediate-1
mkdir /etc/ssl/test-certs
cp certs/ca-chain.cert.pem certs/ca-demo.bytesare.us.cert.pem certs/revoked.ca-demo.bytesare.us.cert.pem private/ca-demo.bytesare.us.key.pem private/revoked.ca-demo.bytesare.us.key.pem crl/intermediate-1.crl.pem /etc/ssl/test-certs/
Apache needs the private key converted without a password,
otherwise the password has to be entered at every start.
cd /etc/ssl/test-certs/
openssl rsa -in ca-demo.bytesare.us.key.pem -out ca-demo.bytesare.us.nopass.key.pem
openssl rsa -in revoked.ca-demo.bytesare.us.key.pem -out revoked.ca-demo.bytesare.us.nopass.key.pem
chown root:www-data -R .
chmod 640 *
cp intermediate-1.crl.pem /var/www/html/
Setup your local system
We pretend to be ca-demo.bytesare.us
, and try it on the local machine.
Add the following line to your hosts file:
127.0.0.1 ca-demo.bytesare.us
Setup Apache
The proxy for the OCSP responder is set up on port 80
in /etc/apache2/sites-enabled/000-default.conf
:
<VirtualHost *:80>
ServerName ca-demo.bytesare.us
DocumentRoot /var/www/html
LogLevel info
ErrorLog ${APACHE_LOG_DIR}/demo-ca.http.error.log
CustomLog ${APACHE_LOG_DIR}/demo-ca.http.access.log combined
<Location /ocsp/intermediate-1>
ProxyPass http://127.0.0.1:2560/
</Location>
</VirtualHost>
The server certificate and the client crl and trusted ca is configured
in /etc/apache2/sites-enabled/default-ssl.conf
:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName ca-demo.bytesare.us
DocumentRoot /var/www/html-ssl
LogLevel info ssl:debug
ErrorLog ${APACHE_LOG_DIR}/demo-ca.ssl.error.log
CustomLog ${APACHE_LOG_DIR}/demo-ca.ssl.access.log combined
# Server certificate configuration:
SSLEngine on
SSLCertificateChainFile /etc/ssl/test-certs/ca-chain.cert.pem
#SSLCertificateFile /etc/ssl/test-certs/ca-demo.bytesare.us.cert.pem
#SSLCertificateKeyFile /etc/ssl/test-certs/ca-demo.bytesare.us.nopass.key.pem
SSLCertificateFile /etc/ssl/test-certs/revoked.ca-demo.bytesare.us.cert.pem
SSLCertificateKeyFile /etc/ssl/test-certs/revoked.ca-demo.bytesare.us.nopass.key.pem
# Client certificate configuration:
SSLCACertificateFile /etc/ssl/test-certs/ca-chain.cert.pem
SSLCARevocationFile /etc/ssl/test-certs/intermediate-1.crl.pem
SSLCARevocationCheck leaf
# Require a client cert (only) in /protected-area:
SSLVerifyClient none
<Location /protected-area>
SSLVerifyClient require
SSLVerifyDepth 10
</Location>
</VirtualHost>
</IfModule>
Restart apache
After the configuration has been changed.
apachectl configtest
systemctl restart apache2
Start the OCSP Responder process
And test the responder using the ca-demo.bytesare.us
domain routed through the Apache listenting on localhost.
cd /root/DemoCA/intermediate-1
openssl ocsp -url http://localhost:2560/ocsp -text -rmd sha256 -index index.txt -CA certs/ca-chain.cert.pem -rkey private/ocsp.key.pem -rsigner certs/ocsp.cert.pem > /var/log/apache2/demo-ca.ocsp.log
# Check if apache proxies ocsp correctly (in a second terminal)
cd /root/DemoCA/intermediate-1
openssl ocsp -CAfile /etc/ssl/test-certs/ca-chain.cert.pem -url http://ca-demo.bytesare.us/ocsp/intermediate-1 -issuer /etc/ssl/test-certs/ca-chain.cert.pem -cert /etc/ssl/test-certs/ca-demo.bytesare.us.cert.pem
Import the Intermediate CA certificate to a browser
In a company environment, the client administrator sets the root CA as trusted,
in our test case we will do this by hand in our browser only.
Copy cert chain to a readable location:
cd /root/DemoCA/intermediate-1
cp certs/ca-chain.cert.pem /tmp/
chmod +r /tmp/ca-chain.cert.pem
In firefox, open Settings
, goto Privacy and Security
, click on View Certificates
and open the tab Authorities
.
Then, import the ca-chain.pem
file to accept our CA. Check if the Intermediate CA has been added to the list after the import.
Import the client certificate to a browser
Copy client certs to a readable location:
cp /home/carl/This email address is being protected from spambots. You need JavaScript enabled to view it. /home/luzifer/This email address is being protected from spambots. You need JavaScript enabled to view it. /tmp/
chmod +r /tmp/*.cert.p12
In firefox, open Settings
, goto Privacy and Security
, click on View Certificates
and open the tab Your Certificates
.
Then, import the
file. Check if the client cert has been added to the list after the import.
Optionally, import the
file. Check if the client cert has been added to the list after the import.
Showtime: Perform connection tests with your browser
Look at the Apache logs while doing this:
tail -fn0 /var/log/apache2/demo-ca*.log /var/log/apache2/ocsp.log
1. Check the browser connection to the https page
Open up the test page, it should load without errors.
Check the server certificate next to the address bar visually.
You should see in your apache logs, that the browser has also sent an OCSP request to our responder.
==> /var/log/apache2/demo-ca.http.access.log <==
127.0.0.1 - - [22/Mar/2019:20:11:17 +0100] "POST /ocsp/intermediate-1 HTTP/1.1" 200 2594 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0"
==> /var/log/apache2/demo-ca.ssl.access.log <==
127.0.0.1 - - [22/Mar/2019:20:11:17 +0100] "GET / HTTP/1.1" 200 6163 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0"
2. Check browser connection with client cert
Open up the location that requires client authentication and use the imported client certificate named carl.
The logs show the successful CRL check:
==> /var/log/apache2/demo-ca.ssl.error.log <==
[Fri Mar 22 20:32:09.087400 2019] [ssl:debug] [pid 30421:tid 140481960511232] ssl_engine_kernel.c(1585): [client 127.0.0.1:36704] AH02275: Certificate Verification, depth 0, CRL checking mode: leaf (1) [subject: emailAddress=This email address is being protected from spambots. You need JavaScript enabled to view it. ,CN=Carl der Tester,L=Innsbruck,ST=Tirol,C=AT / issuer: CN=BytesAreUs GmbH Intermediate CA 1,OU=BytesAreUs GmbH Certificate Authority,O=BytesAreUs GmbH,ST=Vienna,C=AT / serial: 1001 / notbefore: Mar 22 16:13:37 2019 GMT / notafter: Mar 31 16:13:37 2020 GMT]
==> /var/log/apache2/demo-ca.ssl.access.log <==
127.0.0.1 - - [22/Mar/2019:20:32:06 +0100] "GET /protected-area/ HTTP/1.1" 200 13479 "https://ca-demo.bytesare.us/" "Mozilla/5.0 (X11; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0"
3. Check browser connection with a revoked client cert
Open up the location that requires client authentication and use the imported client certificate named luzifer.
The Browser refuses access indicating the revocation:
Secure Connection Failed
An error occurred during a connection to ca-demo.bytesare.us.
SSL peer rejected your certificate as revoked.
Error code: SSL_ERROR_REVOKED_CERT_ALERT
The server logs show an error 403 and the revocation error:
==> /var/log/apache2/demo-ca.ssl.error.log <==
[Fri Mar 22 20:36:53.040334 2019] [ssl:info] [pid 30421:tid 140481728079616] [client 127.0.0.1:36716] AH02276: Certificate Verification: Error (23): certificate revoked [subject: emailAddress=This email address is being protected from spambots. You need JavaScript enabled to view it. ,CN=Luzifer der Teufel,L=Innsbruck,ST=Tirol,C=AT / issuer: CN=BytesAreUs GmbH Intermediate CA 1,OU=BytesAreUs GmbH Certificate Authority,O=BytesAreUs GmbH,ST=Vienna,C=AT / serial: 1002 / notbefore: Mar 22 16:20:39 2019 GMT / notafter: Mar 31 16:20:39 2020 GMT]
[Fri Mar 22 20:36:53.040622 2019] [ssl:error] [pid 30421:tid 140481728079616] SSL Library Error: error:1417C086:SSL routines:tls_process_client_certificate:certificate verify failed
==> /var/log/apache2/demo-ca.ssl.access.log <==
127.0.0.1 - - [22/Mar/2019:20:36:49 +0100] "GET /protected-area/ HTTP/1.1" 403 11114 "https://ca-demo.bytesare.us/" "Mozilla/5.0 (X11; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0"
4. Check browser connection to a page with a revoked server cert
If you use the revoked server certificate on apache,
(just uncomment the two revoked.
lines in the apache config file and restart the server)
the browser will reject access because of the negative OCSP query.
Secure Connection Failed
An error occurred during a connection to
ca-demo.bytesare.us
.
Peer’s Certificate has been revoked.
Error code: SEC_ERROR_REVOKED_CERTIFICATE
The server logs show the start of a TLS handshake, then the negative OCSP Response.
No actual https response shows up, because the browser terminated the handshake:
==> /var/log/apache2/demo-ca.ssl.error.log <==
[Fri Mar 22 20:50:17.207959 2019] [ssl:info] [pid 32219:tid 140240362641152] [client 127.0.0.1:36828] AH01964: Connection to child 8 established (server ca-demo.bytesare.us:443)
[Fri Mar 22 20:50:17.224830 2019] [ssl:debug] [pid 32219:tid 140240362641152] ssl_engine_kernel.c(2067): [client 127.0.0.1:36828] AH02041: Protocol: TLSv1.2, Cipher: ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)
==> /var/log/apache2/demo-ca.http.access.log <==
127.0.0.1 - - [22/Mar/2019:20:50:17 +0100] "POST /ocsp/intermediate-1 HTTP/1.1" 200 2612 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0"
==> /var/log/apache2/demo-ca.ocsp.log <==
OCSP Response Data:
Produced At: Mar 22 19:50:17 2019 GMT
Certificate ID:
Serial Number: 1003
Cert Status: revoked
Revocation Time: Mar 22 16:25:49 2019 GMT
==> /var/log/apache2/demo-ca.ssl.error.log <==
[Fri Mar 22 20:50:17.262845 2019] [ssl:debug] [pid 32219:tid 140240362641152] ssl_engine_io.c(1103): [client 127.0.0.1:36828] AH02001: Connection closed to child 8 with standard shutdown (server ca-demo.bytesare.us:443)
- Details
- Written by: andre
- Category: Uncategorised
- Hits: 8146
Create your own dyndns for your home computer
Setup
Some people want to reach their home computer from the internet but find themselves in the following setup:
- A home computer with a public IP address that can change/is unreliable.
- A host reachable by a reliable public IP address or even better: a domain name.
- A router at home that supports port forwarding.
- No want to register or pay for a dyndns providers.
In such scenarios, we can make the home computer accessible through the public host:
- Setup port forwarding on public host so traffic of a port goes to the home computers.
- Configure home router to forward traffic of one port to the home computer in the LAN.
- Ensure that the system is aware of a public IP address change of the home computer.
Home computer setup
This script is stored on the home computer we want to reach from the public internet, it will update the IP address on the remote computer (which performs the port forwarding).
/home/andre/bin/update-my-ip.sh
#!/bin/bash # ensures a remote computer gets to know this computer's ip # to implement an ip forwarding. # # this script determines this computer's public ip and compate it # to an ip address stored in a file on a remote computer. # if the stored ip is different to the current public ip, # the new ip will be written into the file on the remote computer. # configuration of ssh connections to remote host REMOTE_SSH_USER="remoteUsername" REMOTE_SSH_PORT="22" REMOTE_SSH_HOST="example.com" REMOTE_IP_FILE="ssh-forwarding-ip.txt" # assuming file is in home directory REMOTE_EXEC="ssh $REMOTE_SSH_USER@$REMOTE_SSH_HOST -p $REMOTE_SSH_PORT" check_ip() { if (echo "$1" | grep -qE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'); then return 0 fi echo "ERROR: invalid ip: '$1'" return 1 } # resolve public ip and see what is configured on the remote host: current_ip="$( dig +short myip.opendns.com @resolver1.opendns.com )" remote_ip="$( $REMOTE_EXEC "cat ~/$REMOTE_IP_FILE" )" echo -n "$(date '+%F %T') current_ip: $current_ip remote_ip: $remote_ip " check_ip $current_ip || exit 10 # quit if ip does not look valid check_ip $remote_ip || exit 20 # quit if ip does not look valid # compare ips, quit if no change is necessary: if [ "$current_ip" = "$remote_ip" ]; then echo "Nothing to do, remote IP matches current." exit 0 fi # writing new ip to remote file: $REMOTE_EXEC " cp -v $REMOTE_IP_FILE .$REMOTE_IP_FILE-until-$(date +%F_%T) \ && echo $current_ip > $REMOTE_IP_FILE \ && echo $REMOTE_IP_FILE written"
To make sure the IP stored on the remote computer is always up to date,
create a cronjob that invokes the script above once a minute on the home computer:
andre@nairobi ~ % crontab -e # once per minute: maintain the IP of this computer on bytesare.us, for the port forwarding: * * * * * bash /home/andre/bin/update-my-ip.sh 2>&1 >> /home/andre/log/update-my-ip.log
Public computer setup
- Details
- Written by: Super User
- Category: Uncategorised
- Hits: 19729
PROBLEM
in terminals, the home and end keys are not working when zsh is the shell. for bash it works in the same terminal, so must be possible to use those keys. must have been something that does bash differently than zsh.INVESTIGATION
the documentation says zsh uses "terminfo" to configure its keybindings:andre@nairobi ~ % vim /etc/zsh/zshrc key=( Home "${terminfo[khome]}" End "${terminfo[kend]}" Insert "${terminfo[kich1]}" Delete "${terminfo[kdch1]}" Up "${terminfo[kcuu1]}" Down "${terminfo[kcud1]}" Left "${terminfo[kcub1]}" Right "${terminfo[kcuf1]}" PageUp "${terminfo[kpp]}" PageDown "${terminfo[knp]}" BackTab "${terminfo[kcbt]}" )on my system, the khome and kend variables are not set:
andre@nairobi ~ % for k in "${(@k)terminfo}"; do echo $k; done | sort | grep -E '(khome|kend|kich1|kbs|kdch1|kcuu1|kcud1|kcub1|kcuf1|kpp|knp)' kbs kcub1 kcud1 kcuf1 kcuu1 kdch1 kich1 knp kppbut why? lets see how the terminfo database is built.
andre@nairobi /etc/terminfo % cat README This directory is for system-local terminfo descriptions. By default, ncurses will search ${HOME}/.terminfo first, then /etc/terminfo (this directory), then /lib/terminfo, and last not least /usr/share/terminfo.let's see what terminfo applies currently. that one we will try to fix.
andre@nairobi /lib/terminfo % echo $TERM xterm-colorfind the config file:
andre@nairobi /lib/terminfo % for i in ${HOME}/.terminfo /etc/terminfo /lib/terminfo /usr/share/terminfo; do echo; echo "$i"; find $i -type f -name "xterm-color" -ls; done /home/andre/.terminfo find: `/home/andre/.terminfo': No such file or directory /etc/terminfo /lib/terminfo 1049857 4 -rw-r--r-- 1 root root 1569 Sep 17 2014 /lib/terminfo/x/xterm-color /usr/share/terminfocheck what is set in this terminfo entry:
we can see the same keys as they are listed above.
andre@nairobi ~ % infocmp ============ xterm-color | grep -Eo '(khome|kend|kich1|kbs|kdch1|kcuu1|kcud1|kcub1|kcuf1|kpp|knp)=[^,]*,' | sort kbs=\177, kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA, kdch1=\E[3~, kich1=\E[2~, knp=\E[6~, kpp=\E[5~,
SOLUTION
lets see if we can add the missing capability into the terminfo database.as shown here: https://www.jbase.com/r5/knowledgebase/howto/general/common/CreateTerminfo/modify.htm
we can start with a copy in ${HOME}/.terminfo dir to start experimenting, without modifying system files.
but first we need to find out what are the proper sequences we add.
when pressing left-arrow, right-arrow, bild-auf, bild-ab, home and end using showkey -a, i get this output:
andre@nairobi ~/tmp % showkey -a Press any keys - Ctrl-D will terminate this program ^[[D 27 0033 0x1b # left-arrow ^[[C 27 0033 0x1b # right-arrow ^[[5~ 27 0033 0x1b # page up ^[[6~ 27 0033 0x1b # page down ^[[H 27 0033 0x1b # home ^[[F 27 0033 0x1b # endlooks like we can add the entries of home and end like this.
e.g. Left-Arrow cursor key:
output of showkey -a: "^[[D" corresponding entry in dump: "kcub1=\EOD,"i guess we can replace the "^[[" by "\EO" to obtain the correct values for khome and kend. lets dump the entry and modify it:
andre@nairobi ~ % cd ~/tmp/ andre@nairobi ~/tmp % infocmp xterm-color > xterm-color.ti andre@nairobi ~/tmp % cp xterm-color.ti xterm-color.ti.orig andre@nairobi ~/tmp % vim xterm-color.tithe keys in the dump file are sorted, lets add it in order:
for Home: add "khome=\EOH, " between "kfnd=\E[1~, kich1=\E[2~": for End: and "kend=\EOF, " between "kdch1=\E[3~, kf1=\E[11~,":in my case, the modifications were:
andre@nairobi ~/tmp % diff xterm-color.ti xterm-color.ti.orig 15c15 < kdch1=\E[3~, kend=\EOF, kf1=\E[11~, kf10=\E[21~, kf11=\E[23~, --- > kdch1=\E[3~, kf1=\E[11~, kf10=\E[21~, kf11=\E[23~, 20c20 < kfnd=\E[1~, khome=\EOH, kich1=\E[2~, kmous=\E[M, knp=\E[6~, kpp=\E[5~, --- > kfnd=\E[1~, kich1=\E[2~, kmous=\E[M, knp=\E[6~, kpp=\E[5~,compile the .ti file and check if it was created in the users terminfo:
andre@nairobi ~/tmp % mkdir -p ${HOME}/.terminfo/x andre@nairobi ~/tmp % tic xterm-color.ti andre@nairobi ~/tmp % find ~/.terminfo -type f -ls 1329052 4 -rw-r--r-- 1 andre andre 1443 Mar 18 13:20 /home/andre/.terminfo/x/xterm-colormake sure you have this in your .zshrc or /etc/zsh/zshrc:
# put cursor to end of line when end is pressed bindkey "${key[End]}" end-of-line # put cursor to start of line when home is pressed bindkey "${key[Home]}" beginning-of-linestart a new xterm (! note, not only a new shell in the same terminal) and check if the keys are now present:
andre@nairobi ~ % infocmp xterm-color | grep -Eo '(khome|kend|kcub1)=[^,]*,' | sort kcub1=\EOD, kend=\EOF, khome=\EOH,now, check if your home and end keys are finally working! !!!!! YES, AFTER SO MANY YEARS !!!!!
- Details
- Written by: andre
- Category: Uncategorised
- Hits: 30005
After almost every holiday i find myself in the same problem:
I have made pictures with multiple cameras, phones and maybe there are some pics sent by friends.
Every camera has its own pattern how the files are named, if you want to watch them chronologically, you can sort them by hand or you use the jpeg timestamp and some lines of shell code:
#!/bin/bash TARGET="/tmp/chronosort-`date +%F`-$RANDOM" mkdir "$TARGET" echo "target directory: $TARGET" find . -type f | while read PIC; do echo PIC: ${PIC} if [ -f "$PIC" ]; then # see if PIC is a file if [[ "$(file -b --mime-type "$PIC" )" == "image/jpeg" ]]; then TIMESTAMP_STRING=$(exiv2 "$PIC" | grep -i timestamp | grep -Eo "[0-9].*[0-9]") # echo "timestamp string from exif data: $TIMESTAMP_STRING" # convert the exif string to a date: DATE="$( date -d "$( echo ${TIMESTAMP_STRING} \ | sed 's|\([0-9]*\):\([0-9]*\):\([0-9]*\) \([0-9]*\):\([0-9]*\):\([0-9]*\)|\1/\2/\3 \4:\5:\6|g' )" )" # apply offset for specific camera model (optional) if ( exiv2 "$PIC" | grep "Camera" | grep -qi "casio" ); then echo modifying time for casio camera... # DATE="$( date -d "$DATE -31 minutes" )" fi echo "DATE: ${DATE}" DATE_FILENAME=$( date -d "$DATE" "+%Y-%m-%d_%H:%M:%S" ) TARGET_NAME="${DATE_FILENAME}__$(basename "$PIC" )" TARGET_FILE="$TARGET/$TARGET_NAME" # echo TARGET_FILE: $TARGET_FILE # create dir if needed: mkdir -pv "$(dirname "$TARGET_FILE" )" cp -v "$PIC" "$TARGET_FILE" else echo "Not a file, skipping $PIC....." fi echo fi done
- Details
- Written by: andre
- Category: Uncategorised
- Hits: 32418