Skip to main content

Posts about linux

build a test labo for cisco certificate

I like cli environment, so I prefer to use dynagen with dynamips.

The last version of debian which offer dynagen deb package is debian10 buster, so I select it.

Install related packages.

version=0.2.22
sed -i.bak 's/ main$/ main contrib non-free/' /etc/apt/sources.list \
&& apt update && apt upgrade -y \
&& DEBIAN_FRONTEND noninteractive apt install -y \
 vpcs \
 openvswitch-switch \
 snmp snmptrapd \
 freeradius \
 postfix mailutils \
 tcpdump \
 tftpd-hpa tftp-hpa \
 telnet \
 tmux \
&& curl -fsSL https://toolbelt.treasuredata.com/sh/install-debian-buster-td-agent4.sh | sudo sh \
&& wget https://github.com/GNS3/dynamips/archive/refs/tags/v${version}.tar.gz \
&& tar zxf v${version}.tar.gz \
&& rm v${version}.tar.gz \
&& cd dynamips-${version} \
&& apt install -y gcc cmake libelf-dev libpcap-dev make musl-dev linux-headers-amd64 \
&& mkdir -p dynamips-${version}/build \
&& cd dynamips-${version}/build \
&& cmake .. \
&& make \
&& make install \
&& rm -rf dynamips-${version} \
&& apt remove -y gcc cmake make musl-dev linux-headers \
&& apt autoremove -y \
&& apt install -y dynagen

openvswitch

create openvswitch virtual bridge and tap device.

sudo ovs-vsctl show
sudo ovs-vsctl add-br br0

sudo ip link set br0 up
ip link show br0

sudo ip address add 10.2.0.1/24 brd + dev br0
ip address show br0

sudo ip tuntap add dev tap0 mode tap
sudo ovs-vsctl add-port br0 tap0
sudo ip link set tap0 up
sudo ip route add 10.2.0.0/16 dev br0
ip link show tap0

everytime you restart the computer, you have to add tap device to the bridge

sudo ovs-vsctl show
sudo ip address add 10.2.0.1/24 brd + dev br0
sudo ip tuntap add dev tap0 mode tap
sudo ip link set tap0 up
sudo ip link set br0 up
sudo ip route add 10.2.0.0/16 dev br0
ip link show tap0

you have to start dynamips by root user to connect to tap device.

sudo dynamips -H 127.0.0.1:7200

you can start dynagen by your own user.

dynagen labo.net

you can connect tap device to dynamips labo with dynagen using NIO_tap:tap0 like below:

NIO_tap:tap0

vpcs

you can connect vpcs to dynagen using NIO_udp device like below:

NIO_udp:30000:127.0.0.1:20000

rsyslog

change rsyslog config to receive syslog message.

$ sudo cp -pi /etc/rsyslog.conf{,.000}
$ sudo vi /etc/rsyslog.conf
$ diff -u /etc/rsyslog.conf{,.000}
@@ -13,8 +13,8 @@
 #module(load="immark")  # provides --MARK-- message capability

 # provides UDP syslog reception
-module(load="imudp")
-input(type="imudp" port="514")
+#module(load="imudp")
+#input(type="imudp" port="514")

 # provides TCP syslog reception
 #module(load="imtcp")
@@ -90,7 +90,3 @@
 # Emergencies are sent to everybody logged in.
 #
 *.emerg                                :omusrmsg:*
-
-
-
-local0.*                       -/var/log/local0.log

$ sudo touch /var/log/local0.log
$ sudo systemctl restart rsyslog
$ tail -f /var/log/local0.log

chronyd

change chronyd config to serve ntp clock to labo network.

In this example, 10.2.0.0/16 is labo network address range

$ sudo cp -pi /etc/chrony/chrony.conf{,.000}
$ sudo vi /etc/chrony/chrony.conf
$ diff -u /etc/chrony/chrony.conf{,.000}
@@ -29,5 +29,3 @@
 # Step the system clock instead of slewing it if the adjustment is larger than
 # one second, but only in the first three clock updates.
 makestep 1 3
-
-allow 10.2.0.0/16

$ sudo systemctl restart chrony
$ chronyc sources

snmp

on cisco device

# snmp-server community cisco ro
$ snmpwalk -v 1 10.2.0.254 -c cisco 1.3.6.1.2.1.2.2.1.10
$ snmpwalk -v 1 10.2.0.254 -c cisco 1.3.6.1.2.1.2.2.1.16

snmptrap

$ sudo cp -pi /etc/snmp/snmptrapd.conf{,.000}
$ sudo vi /etc/snmp/snmptrapd.conf

$ diff -u /etc/snmp/snmptrapd.conf{,.000}
@@ -16,7 +16,6 @@
 #
 #authCommunity log,execute,net private 
 #authCommunity log,execute,net public
-authCommunity log cisco
 #
 ## send mail when get any events
 #traphandle default /usr/bin/traptoemail -s smtp.example.org foobar@example.org

$ sudo systemctl start snmptrapd.service
$ tail -f /var/log/messages

on cisco device

# snmp-server host address traps version 1 cisco 
# snmp-server enable traps
# int fa0/0
# no shut

freeradius

$ sudo cp -pi  /etc/freeradius/3.0/clients.conf{,.000}
$ sudo vi  /etc/freeradius/3.0/clients.conf
$ sudo diff -u /etc/freeradius/3.0/clients.conf{,.000}
@@ -266,8 +266,3 @@
 #              secret = testing123
 #      }
 #}
-client ciscolabo {
-       ipaddr = 10.2.0.0/16
-       secret = radiussecret
-}
-
$ sudo ls -l /etc/freeradius/3.0/mods-config/files/authorize{,.000}
$ sudo vi /etc/freeradius/3.0/mods-config/files/authorize
$ sudo diff -u /etc/freeradius/3.0/mods-config/files/authorize{,.000}
--- /etc/freeradius/3.0/mods-config/files/authorize     2022-11-19 20:50:54.008631636 +0900
+++ /etc/freeradius/3.0/mods-config/files/authorize.000 2022-08-28 04:29:38.000000000 +0900
@@ -1,4 +1,3 @@
-cisco1 Cleartext-Password := "cisco1pass"
 #
 #      Configuration file for the rlm_files module.
 #      Please see rlm_files(5) manpage for more information.

restart freeradius and test

$ sudo systemctl restart freeradius
$ sudo apt install -y freeradius-utils
$ radtest cisco1 cisco1pass 127.0.0.1 1812 testing123
$ radtest cisco1 cisco1pass 10.2.0.1 1812 radiussecret

on cisco device

conf t
aaa new-model
radius-server host 10.2.0.1 auth-port 1812 key radiussecret
aaa group server radius freeradius
server 10.2.0.1 auth-port 1812
exit
exit

test

test aaa group freeradius cisco1 cisco1pass port 1812 new-code

config vty settings

conf t
aaa authentication login freeradius group radius
line vty 0 15
login authentication freeradius

telnet from server

telnet 10.2.1.254

td-agent

install fluent-plugin-netflow and change configuration

sudo td-agent-gem install fluent-plugin-netflow
sudo cp -pi /etc/td-agent/td-agent.conf{,.000}
sudo vi /etc/td-agent/td-agent.conf
diff -u /etc/td-agent/td-agent.conf{,.000}
@@ -126,15 +126,3 @@
 #    path /var/log/td-agent/td-%Y-%m-%d/%H.log
 #  </store>
 #</match>
-
-<match netflow.*>
-  @type stdout
-</match>
-
-<source>
-  @type netflow
-  tag netflow.event
-  port 5141
-  versions [5, 9]
-</source>
-

test configuration and restart td-agent service

sudo td-agent --dry-run
sudo systemctl restart td-agent.service

on cisco device

conf t
int fa0/0
ip flow ingress
ip flow egress
exit
ip flow-export version 5
ip flow-export destination 10.2.0.1 5141 udp
ip flow-export source fa0/0
end
show ip cache flow

after a while confirm td-agent log file

sudo tail -f /var/log/td-agent/td-agent.log

postfix

$ sudo cp -pi /etc/postfix/main.cf{,.000}
$ sudo vi /etc/postfix/main.cf
$ diff -u /etc/postfix/main.cf{,.000}
@@ -37,11 +37,12 @@
 myhostname = ip-10-0-0-73.ap-northeast-1.compute.internal
 alias_maps = hash:/etc/aliases
 alias_database = hash:/etc/aliases
-myorigin = /etc/mailname
-mydestination = $myhostname, ip-10-0-0-73.ap-northeast-1.compute.internal, localhost.ap-northeast-1.compute.internal, , localhost
+mydestination = localdomain, $myhostname, ip-10-0-0-73.ap-northeast-1.compute.internal, localhost.ap-northeast-1.compute.internal, localhost
 relayhost = 
-mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
+mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 10.2.0.0/16
 mailbox_size_limit = 0
 recipient_delimiter = +
-inet_interfaces = all
+inet_interfaces = 127.0.0.1, [::1], 10.2.0.1
+default_transport = error
+relay_transport = error
 inet_protocols = all

$ sudo systemctl restart postfix

test

$ cat << END | mail -s 'test subject' admin
> test body
> .
> END

test from cisco device

track 1 interface FastEthernet1/0 line-protocol
event manager applet eemtest
event track 1 state down
action 1.0 cli command "enable"
action 2.0 cli command "show int fa1/0"
action 3.0 mail server "10.2.0.1" to "admin" from "labo@example.com" subject "interface down" body "$_cli_result"

tcpdump

Of courese, Dynagen has capture function, if you prefer it, try local SPAN on cisco device

conf t
int fa1/0
no shut
int fa1/15
no shut
exit
monitor session 1 source interface FastEthernet 1/0
monitor session 1 destination interface FastEthernet 1/15

capture stream and save it to file.

sudo tcpdump -i br0 -w capture.dump
sudo tcpdump -r capture.dump -n -e -v -x | less

tftp

get test

$ echo helloworld | sudo tee -a /srv/tftp/helloworld
$ tftp 10.2.0.1 -c get helloworld

put test

$ mv helloworld helloworld.1
$ sudo touch /srv/tftp/helloworld.1
$ sudo chmod 766 /srv/tftp/helloworld.1
$ cat << END | tftp 10.2.0.1
> put helloworld.1
> END

before test on cisco device

$ sudo touch /srv/tftp/running-config
$ sudo chmod 766 /srv/tftp/running-config

test

# copy start tftp://10.2.0.1/running-config

confirm

$ ls -l /srv/tftp/running-config{,.bak}
$ sudo cp -pi /srv/tftp/running-config{,.bak}

let's encrrypt

certbot certonly \
--dry-run \
-d www.example.net \
-m yourname@example.net \
--preferred-challenges dns-01  \
--server https://acme-v02.api.letsencrypt.org/directory \
--manual \
--manual-auth-hook /home/user/work/letsencrypt/dns01-auth.sh \
--manual-cleanup-hook /home/user/work/letsencrypt/dns01-clean.sh \
--post-hook /home/user/work/letsencrypt/post-hook.sh \
--work-dir /home/user/work/letsencrypt/work \
--logs-dir /home/user/work/letsencrypt/logs \
--config-dir /home/user/work/letsencrypt/conf
  • When you run certbot in non-root user, you have to specify --work-dir, --logs-dir, and --config-dir options. These directories have to be writable with your user.
  • You can only publish new certificate file via certbot. Your new certificate file will pushed under config-dir directory. Afterward, you can deploy it with your deploy tool which you like.
  • The dns-01 challenge authentication only needs DNS validation and don't need to access via 80/tcp nor web server installation on your server. When you use dns-01 challenge, you can use your script to update your dns resource to --manual-auth-hook (for authentication) and --manual-cleanup-hook (for cleanup entry).
    CERTBOT_DOMAIN varaible is used to show domain name which you want to use. CERTBOT_VALIDATION vaibale is used to show validation code.

sample script which create validtion entry for aws route53

sample script which delete validtion entry for aws route53

certbot renew \
--dry-run \
--post-hook /home/user/work/letsencrypt/post-hook.sh \
--work-dir /home/user/work/letsencrypt/work \
--logs-dir /home/user/work/letsencrypt/logs \
--config-dir /home/user/work/letsencrypt/conf
  • Once you get your new certificate, you have to update your certificate periodically.

network time security

Secure NTP with NTS

Chrony supports nts since version 4.0. I tried to build nts server and client.

server configuration

example of chrony 4.2 on ubuntu 22.04 LTS

server time.facebook.com iburst maxpoll 11
server time.google.com   iburst maxpoll 11
server time.apple.com    iburst maxpoll 11

ntsserverkey /etc/chrony/key.pem
ntsservercert /etc/chrony/crt.pem

key.pem and crt.pem are openssl private key and certificate(with intermediate ca certificate) file pair. The certificate needs to include your fqdn of your nts server.

When I put key and crt files in a sub directory of /etc/ssl, below error occured.

Could not set credentials : Error while reading file.

In /var/log/syslog, I found audit log of apparmor which shows it denied for chronyd to open the key file. When I put them in /etc/chrony, I successed to run it.

Before test from client, you have to open not only 123/udp for NTP but also 4460/tcp for NTS-KE.

$ chronyd -Q -t 8 'server mynts.example.com iburst nts'
$ sudo chronyc serverstats

client configuration

example of chrony 4.0 on Debian 11

server mynts.example.com iburst nts
server ptbtime1.ptb.de   iburst nts
server nts.time.nl       iburst nts
server nts.ntp.se        iburst nts

ntstrustedcerts /etc/chrony/cacert.crt

When you use selfsigned CA to make your certificate in the nts server, you have to show your own ca certificate file to chrony.conf in ntstrustedcerts.

wireguard on raspberryrpi

I tried to install wireguard with pivpn on 64bit Raspberry pi OS (buster, 4B), but it failed

$ cat << END > /tmp/pivpn_options.conf                                                                                                                                           
IPv4dev=xx
install_user=pi
VPN=wireguard
pivpnNET=10.x.x.0
subnetClass=24
ALLOWED_IPS="10.x.x.0/24, 192.168.y.0/24"
pivpnMTU=1420
pivpnPORT=51820
pivpnDNS1=1.1.1.1
pivpnHOST=myname.example.com
pivpnPERSISTENTKEEPALIVE=25
UNATTUPG=1
END

$ curl -L https://install.pivpn.io > /tmp/pivpn_install.sh
$ chmod +x /tmp/pivpn_install.sh
$ /tmp/pivpn_install.sh --noipv6 --unattended /tmp/pivpn_options.conf                                                                                                     


:: wireguard is not a supported VPN protocol on arm64 Debian, only 'openvpn' is

I was not able to select wireguard in intereractive interface. It select openvpn automatically.

$ /tmp/pivpn_install.sh --noipv6

Though I successed it on 32bit Raspberry pi OS (bullseye, 3B+) It needs NAPT settings to your pi to make a connection from outside wireguard peer.

I'd like to try it on bookwarm 32bit/64bit when it will be released on the next version of the pi :)

copy partition of sd card

dump partition of original sd card

sudo parted /dev/sdx print
sudo dd if=/dev/sdx1 of=tablet_sdx1.img bs=4M

restore to new sd card

sudo parted /dev/sdx print
sudo dd if=tablet_sdx1.img of=/dev/sdx1 bs=4M

confirm the size of filesystem

sudo mount /dev/sdb1 /media/tmp
df
sudo umount /media/tmp

extend the filesystem (if needed)

sudo apt install --no-install-recommends fatresize
sudo fatresize -i /dev/sdb1
max=$(expr $(sudo fatresize -i /dev/sdb1 | awk -F: '$1~/Max size/{print $2}') / 1024)
sudo fatresize -s ${max}k /dev/sdb1
sudo fatresize -i /dev/sdb1

confirm the size of filesystem

sudo mount /dev/sdb1 /media/tmp
df

k3s using docker runtime

install single-node k3s cluster instead of containerd

I can install with these commands on debian buster arm64 though can not on bullseye.

at first intall docker

sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
sudo docker run hello-world

then install k3

curl -sfL https://get.k3s.io | sh -s - --docker
systemctl status k3s

uninstall

/usr/local/bin/k3s-uninstall.sh

create deployment

create yaml file

cat <<EOF > nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx-test
        image: nginx-test:latest
        imagePullPolicy: Never
        ports:
        - containerPort: 80
EOF

create and confirm the deployment

sudo kubectl create -f nginx-deployment.yaml
sudo kubectl get deploy
sudo kubectl get pod
sudo kubectl exec -it <pod name> -- curl localhost

create service

create yaml file

cat <<EOF > nginx-service.yaml
kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - protocol: TCP
    targetPort: 80
    port: 80

create and confirm the service

sudo kubectl create -f nginx-service.yaml
sudo kubectl get svc
curl x.x.x.x

modify service

sudo kubectl apply -f nginx-deployment.yaml
sudo kubectl get svc

delete srvice

sudo kubectl delete svc <service name>

delete deployment

sudo kubectl delete -f ./nginx-deployment.yaml

Grandstream GXP1610

GXP1610 は 1SIP 対応の IP電話機。 液晶バックライトを搭載してたり、2SIPに対応していたり、PoE対応、Gigabit Ethernet対応してるような上級機がある中の入門機。

以下、備忘録

  • 説明書はペラペラ。必要な情報は自ら取りに行く姿勢が求められる
  • スタンドの取り付け向きに注意
  • スイッチからのケーブルをLANに、PCへのケーブルをPCへ接続すると、ハブ(?)として動作してくれる(10/100Mbps)
  • DHCPが有効なネットワークに接続してほどなくするとIPアドレスを取れる
  • ディスプレイにIPアドレスが表示されるので、PCからWebアクセスすると、管理画面を表示できる
  • 管理画面の初期パスワードは同梱の説明書に記載されている。初めてログインすると変更が促される。ログイン時に5回間違えるとやばい
  • Web UI、端末の液晶とも、多言語対応(日本語表示可能)
  • 試していないがIPアドレスは静的アドレスを設定可能なようだ
  • 設定済みのAsteriskに収容するだけなら、Web UI で SIPサーバ、ID、パスワード等を設定するだけなので、簡単
  • SIPアカウント設定の画面で、Voice Mail Access Number を設定すると、メールアイコンのボタンを押すことで、VoiceMail に架電することができる
  • NTPサーバを指定できる
  • Syslog転送できる(facility=user)
  • 試していないけど、SNMPサーバを指定できるようだ
  • 試していないけど、LDAPの電話帳が使えるようだ

rpm package management

list installed packages

# rpm -qa [package name]
# yum list [package name]
# dnf list [package name]

install package / rpm file

# rpm -ivh <rpm file name>
# microdnf install <package name>
# dnf install <package name>

list installed files

# rpm -ql <package name>

list repositories

# yum repolist [repository name] [-v]
# microdnf repolist
# dnf repolist [repository name] [-v]

show packages contained in the repository

# yum repository-packages [repository name] list
# dnf repository-packages [repository name] list

disable or enable repository with config-manager module contained in yum-utils

# yum config-manager <--set-disabled|--set-enabled> epel
# dnf config-manager <--set-disabled|--set-enabled> epel

update installed packages

# yum update
# microdnf update
# dnf update

download rpm file with yumdownloader which is a part of yum-utils package.

# yumdownloder <package name>
# yumdownloder <package name>.<version>.<architecture>

list files contained in a rpm file

# rpm2cpio <rpm file> | cpio --list

extract a rpm file in the current directory

# rpm2cpio <rpm file> | cpio -id
# find . -type f

remove installed package

# rpm -e <pakcage name>
# yum remove <pakcage name>
# microdnf remove <pakcage name>
# dnf remove <pakcage name>

remove all cached data

# yum clean all
# microdnf clean
# dnf clean all

show transaction history

# yum history
# dnf history

squid bump

On debian if you want to analyze or cache the content of the ssl traffic with squid, you have to buid your own squid. This is a sample to build squid using apt source package.

build a docker container

make a dockerfile

FROM debian:buster-slim

WORKDIR /tmp/buildwork
RUN echo 'deb-src http://deb.debian.org/debian buster main' >> /etc/apt/sources.list \
&& apt-get update \
&& apt install --no-install-recommends -y dpkg-dev devscripts build-essential fakeroot libssl-dev libldap2-dev libpam0g-dev libdb-dev cdbs libsasl2-dev debhelper libcppunit-dev libkrb5-dev comerr-dev libcap2-dev libecap3-dev libexpat1-dev libxml2-dev pkg-config libnetfilter-conntrack-dev nettle-dev libgnutls28-dev dh-apparmor ed libdbi-perl libltdl-dev lsb-release libpopt0 logrotate squid-langpack \
&& apt source squid \
&& apt clean \
&& rm -rf /var/lib/apt/lists/*

RUN sed -i.bak -e '/--with-gnutls$/ s/$/ --with-openssl --enable-ssl --enable-ssl-crtd/' squid-4.6/debian/rules \
&& squid-4.6/configure \
&& cd squid-4.6 \
&& debuild -us -uc -b \
&& dpkg -i ../squid_*.deb ../squid-common_*.deb \
&& mkdir -p /var/spool/squid /etc/squid/ssl_cert && chown proxy:proxy /var/spool/squid \
&& cd /tmp && rm -rf /tmp/buildwork

VOLUME ["/var/spool/squid"]
EXPOSE 3128

WORKDIR /var/spool/squid
COPY squid.conf /etc/squid/squid.conf
COPY server.crt /etc/squid/ssl_cert/server.crt
COPY server.key /etc/squid/ssl_cert/server.key

CMD chmod 600 /etc/squid/ssl_cert/server.key \
&& if [ ! -f /var/spool/squid/swap.state ]; then squid -z ; fi \
&& if [ ! -d /var/spool/squid/ssl_db ]; then /usr/lib/squid/security_file_certgen -c -s /var/spool/squid/ssl_db -M 20MB ; chown -R proxy. /var/spool/squid/ssl_db ; fi \
&& squid -N

sample configure file

acl localnet src 192.168.xxx.0/24
acl SSL_ports port 443
acl Safe_ports port 80
acl Safe_ports port 21
acl Safe_ports port 443
acl CONNECT method CONNECT
acl intermediate_fetching transaction_initiator certificate-fetching
http_access allow intermediate_fetching
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
include /etc/squid/conf.d/*
http_access allow localnet
http_access allow localhost
http_access deny all
http_port 3128 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=/etc/squid/ssl_cert/server.crt key=/etc/squid/ssl_cert/server.key
ssl_bump stare all
sslproxy_cert_error allow all
sslcrtd_children 3 startup=1 idle=1
cache_dir ufs /var/spool/squid 100 16 256
coredump_dir /var/spool/squid
refresh_pattern .               129600  33%     525600
dns_nameservers 192.168.xxx.xxx 192.168.xxx.xxx

If you don't have a CA file and private key for it, you need create them. When you already have them, I think you can use intermediate CA signed by your own CA.

$ openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout server.key -out server.crt -subj "/CN=192.168.xxx.xxx" -days 3650

build an image

$ docker build --build-arg http_proxy=http://192.168.xxx.xxx:3142/ -t squid:test .

run a container

$ sudo docker run --rm squid:test squid --version | awk -F: '$1~/options/{print $2}' | sed -e 's/ /\n/g' | grep ssl
'--with-openssl'
'--enable-ssl'
'--enable-ssl-crtd'
$ docker run --rm -p 3128:3128 -v /mnt/squid:/var/spool/squid -d squid:test

test the address and port

$ curl -D - -s http://192.168.xxx.xxx:3128/ -o /dev/null

connecting to HTTPS server

$ https_proxy=http://192.168.xxx.xxx:3128/ curl -v -k -s https://www.google.com/ -o /dev/null
* Uses proxy env variable https_proxy == 'http://192.168.xxx.xxx:3128/'
*   Trying 192.168.xxx.xxx...
* TCP_NODELAY set
* Connected to 192.168.xxx.xxx (192.168.xxx.xxx) port 3128 (#0)
* allocate connect buffer!
* Establish HTTP proxy tunnel to www.google.com:443
> CONNECT www.google.com:443 HTTP/1.1
> Host: www.google.com:443
> User-Agent: curl/7.61.1
> Proxy-Connection: Keep-Alive
> 
< HTTP/1.1 200 Connection established
< 
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
:
:
:
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: C=US; ST=California; L=Mountain View; O=Google LLC; CN=www.google.com
*  start date: May 10 04:04:06 2021 GMT
*  expire date: Aug  2 04:04:05 2021 GMT
*  issuer: CN=192.168.xxx.xxx
*  SSL certificate verify result: self signed certificate in certificate chain (19), continuing anyway.
} [5 bytes data]
> GET / HTTP/1.1
> Host: www.google.com
> User-Agent: curl/7.61.1
> Accept: */*
> 
{ [5 bytes data]
< HTTP/1.1 200 OK
< Date: Wed, 09 Jun 2021 00:22:42 GMT
< Expires: -1
< Cache-Control: private, max-age=0
< Content-Type: text/html; charset=ISO-8859-1
< P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
< Server: gws
< X-XSS-Protection: 0
< X-Frame-Options: SAMEORIGIN
< Set-Cookie: 1P_JAR=2021-06-09-00; expires=Fri, 09-Jul-2021 00:22:42 GMT; path=/; domain=.google.com; Secure
< Set-Cookie: NID=216=ptf-d_HIPGOAjnEf-gbmRDmIg3JnEfjqRRnQghOkyFHrdLy5fXGOhydj5jBHonqOlP5WCzPIKX3kIkdizOXCQ13t4moqXwr-UoOWiRXgYaAkx6gyqe03hjM_hwfin5plUuG3NClONGvvFJo5Mqvar7GFYrSFYOMVCXMXvTJ0d4M; expires=Thu, 09-Dec-2021 00:22:42 GMT; path=/; domain=.google.com; HttpOnly
< Alt-Svc: h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
< Accept-Ranges: none
< Vary: Accept-Encoding
< X-Cache: MISS from bd2e0fa8b95e
< X-Cache-Lookup: MISS from bd2e0fa8b95e:3128
< Transfer-Encoding: chunked
< Via: 1.1 bd2e0fa8b95e (squid/4.6)
< Connection: keep-alive
< 
{ [5 bytes data]
* Connection #0 to host 192.168.xxx.xxx left intact

sample log of other connections

1622798061.167    833 192.168.xxx.xxx NONE/200 0 CONNECT dl.fedoraproject.org:443 - HIER_DIRECT/38.145.60.22 -
1622798061.539    260 192.168.xxx.xxx TCP_MISS/200 16108 GET https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm - HIER_DIRECT/38.145.60.22 application/x-rpm
1622798109.029    496 192.168.xxx.xxx NONE/200 0 CONNECT dl.fedoraproject.org:443 - HIER_DIRECT/38.145.60.22 -
1622798109.130      1 192.168.xxx.xxx TCP_MEM_HIT/200 16115 GET https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm - HIER_NONE/- application/x-rpm

squid nobump

The squid packages of debian doesn not support sslbump. It only redirects ssl traffic. We can not analyze or cache the content of the ssl traffic.

build a docker container

make a dockerfile

FROM debian:buster-slim

RUN apt-get update \
&& apt install -y squid \
s&& apt clean \
&& rm -rf /var/lib/apt/lists/*

VOLUME ["/var/spool/squid"]
EXPOSE 3128

WORKDIR /var/spool/squid
COPY squid.conf /etc/squid/squid.conf

CMD if [ ! -f /var/spool/squid/swap.state ]; then squid -z ; sleep 2; fi \
&& squid -N

sample configure file

acl localnet src 192.168.xxx.0/24
acl SSL_ports port 443
acl Safe_ports port 80
acl Safe_ports port 21
acl Safe_ports port 443
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
include /etc/squid/conf.d/*
http_access allow localnet
http_access allow localhost
http_access deny all
http_port 3128
cache_dir ufs /var/spool/squid 100 16 256
coredump_dir /var/spool/squid
refresh_pattern .               129600  33%     525600
dns_nameservers 192.168.xxx.xxx 192.168.xxx.xxx

build an image

$ docker build --build-arg http_proxy=http://192.168.xxx.xxx:3142/ -t squid:test .

run a container

$ docker run --rm squid:test squid --version | awk -F: '$1~/options/{print $2}' | sed -e 's/ /\n/g' | grep ssl
(result will be nothing)
$ docker run --rm -p 3128:3128 -v /mnt/squid:/var/spool/squid -d squid:test

test the address and port

$ curl -D - -s http://192.168.xxx.xxx:3128/ -o /dev/null

connecting to HTTP server

without proxy

$ curl -v -s http://ftp.yz.yamagata-u.ac.jp/pub/linux/centos/5.11/readme -o /dev/null
*   Trying 2001:df0:25e:e100::3...
* TCP_NODELAY set
* Connected to ftp.yz.yamagata-u.ac.jp (2001:df0:25e:e100::3) port 80 (#0)
> GET /pub/linux/centos/5.11/readme HTTP/1.1
> Host: ftp.yz.yamagata-u.ac.jp
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Mon, 07 Jun 2021 00:59:01 GMT
< Server: Apache/2.4.46 (Unix) OpenSSL/1.1.1k
< Upgrade: h2,h2c
< Connection: Upgrade
< Last-Modified: Mon, 03 Apr 2017 11:34:28 GMT
< ETag: "14b-54c418ac05900"
< Accept-Ranges: bytes
< Content-Length: 331
<
{ [331 bytes data]
* Connection #0 to host ftp.yz.yamagata-u.ac.jp left intact

with proxy

$ http_proxy=http://192.168.xxx.xxx:3128/ curl -v -s http://ftp.yz.yamagata-u.ac.jp/pub/linux/centos/5.11/readme -o /dev/null
* Uses proxy env variable http_proxy == 'http://192.168.xxx.xxx:3128/'
*   Trying 192.168.xxx.xxx...
* TCP_NODELAY set
* Connected to 192.168.xxx.xxx (192.168.xxx.xxx) port 3128 (#0)
> GET http://ftp.yz.yamagata-u.ac.jp/pub/linux/centos/5.11/readme HTTP/1.1
> Host: ftp.yz.yamagata-u.ac.jp
> User-Agent: curl/7.64.0
> Accept: */*
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 OK
< Date: Mon, 07 Jun 2021 00:58:26 GMT
< Server: Apache/2.4.46 (Unix) OpenSSL/1.1.1k
< Last-Modified: Mon, 03 Apr 2017 11:34:28 GMT
< ETag: "14b-54c418ac05900"
< Accept-Ranges: bytes
< Content-Length: 331
< X-Cache: MISS from e3b21f81fdd2
< X-Cache-Lookup: MISS from e3b21f81fdd2:3128
< Via: 1.1 e3b21f81fdd2 (squid/4.6)
< Connection: keep-alive
<
{ [331 bytes data]
* Connection #0 to host 192.168.xxx.xxx left intact

when cache hit

< Age: 358
< X-Cache: HIT from e3b21f81fdd2
< X-Cache-Lookup: HIT from e3b21f81fdd2:3128

squid log

$ docker exec xxxxxxxxxxxx tail /var/log/squid/access.log
:
1623026732.001    265 192.168.xxx.xxx TCP_MISS/200 685 GET http://ftp.yz.yamagata-u.ac.jp/pub/linux/centos/5.11/readme - HIER_DIRECT/133.24.248.17 -
1623027089.025      0 192.168.xxx.xxx TCP_MEM_HIT/200 693 GET http://ftp.yz.yamagata-u.ac.jp/pub/linux/centos/5.11/readme - HIER_NONE/- -

connecting to HTTPS server

without proxy

$ curl -v -k -s https://www.google.com/ -o /dev/null 
*   Trying 142.250.196.132...
* TCP_NODELAY set
* Connected to www.google.com (142.250.196.132) port 443 (#0)
:

with proxy

$ https_proxy=http://192.168.xxx.xxx:3128/ curl -v -k -s https://www.google.com/ -o /dev/null 
* Uses proxy env variable https_proxy == 'http://192.168.xxx.xxx:3128/'
*   Trying 192.168.xxx.xxx...
* TCP_NODELAY set
* Connected to 192.168.xxx.xxx (192.168.xxx.xxx) port xxxxx (#0)
* allocate connect buffer!
* Establish HTTP proxy tunnel to www.google.com:443
> CONNECT www.google.com:443 HTTP/1.1
> Host: www.google.com:443
> User-Agent: curl/7.61.1
> Proxy-Connection: Keep-Alive
> 
< HTTP/1.1 200 Connection established
< 
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
:

squid log. The ssl connection is just tunneled.

$ sudo docker exec xxxxxxxxxxxx tail /var/log/squid/access.log
:
1622950724.481    170 192.168.xxx.xxx TCP_TUNNEL/200 18439 CONNECT www.google.com:443 - HIER_DIRECT/172.217.175.4 -