Skip to content

Commit 2bf384d

Browse files
Merge pull request #4 from esnet/netops2devops/fix-installer-script
add multi-arch release builds and systemd service support. Fix installer script.
2 parents b4f6a35 + 23af7f2 commit 2bf384d

4 files changed

Lines changed: 171 additions & 30 deletions

File tree

.github/workflows/ci.yml

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,18 @@ jobs:
103103
govulncheck ./...
104104
105105
build:
106-
name: Build
106+
name: Build (${{ matrix.os }}_${{ matrix.arch }})
107107
runs-on: ubuntu-latest
108108
needs: [lint, security-scan, test]
109+
strategy:
110+
matrix:
111+
include:
112+
- os: linux
113+
arch: amd64
114+
goarch: amd64
115+
- os: linux
116+
arch: arm64
117+
goarch: arm64
109118
steps:
110119
- name: Checkout code
111120
uses: actions/checkout@v4
@@ -119,15 +128,35 @@ jobs:
119128
run: |
120129
sudo apt-get update
121130
sudo apt-get install -y libpcsclite-dev
131+
# Install cross-compilation toolchain for arm64
132+
if [ "${{ matrix.arch }}" = "arm64" ]; then
133+
sudo apt-get install -y gcc-aarch64-linux-gnu
134+
fi
135+
136+
- name: Setup dev environment
137+
run: |
138+
mkdir .build
139+
git clone --branch v0.29.0 --depth 1 https://github.com/smallstep/certificates.git .build/certificates/
140+
rm -rf .build/certificates/server && cp -r ./hack/server .build/certificates/server
141+
mkdir -p db
142+
go mod tidy
122143
123144
- name: Build binary
124-
run: make
145+
env:
146+
GOOS: ${{ matrix.os }}
147+
GOARCH: ${{ matrix.goarch }}
148+
CGO_ENABLED: ${{ matrix.arch == 'arm64' && '0' || '1' }}
149+
CC: ${{ matrix.arch == 'arm64' && 'aarch64-linux-gnu-gcc' || '' }}
150+
run: |
151+
BINARY_NAME="step-ca_${{ matrix.os }}_${{ matrix.arch }}"
152+
go build -v -o "${BINARY_NAME}" .
153+
echo "Built ${BINARY_NAME}"
125154
126155
- name: Upload binary artifact
127156
uses: actions/upload-artifact@v4
128157
with:
129-
name: step-ca-linux-amd64
130-
path: step-ca
158+
name: step-ca_${{ matrix.os }}_${{ matrix.arch }}
159+
path: step-ca_${{ matrix.os }}_${{ matrix.arch }}
131160

132161
container-build-and-push:
133162
name: Build and Push Container
@@ -184,18 +213,15 @@ jobs:
184213
- name: Checkout code
185214
uses: actions/checkout@v4
186215

187-
- name: Set up Go
188-
uses: actions/setup-go@v5
216+
- name: Download all build artifacts
217+
uses: actions/download-artifact@v4
189218
with:
190-
go-version: ${{ env.GO_VERSION }}
219+
path: dist
220+
pattern: step-ca_*
221+
merge-multiple: true
191222

192-
- name: Install dependencies
193-
run: |
194-
sudo apt-get update
195-
sudo apt-get install -y libpcsclite-dev
196-
197-
- name: Build binary
198-
run: make
223+
- name: List artifacts
224+
run: ls -la dist/
199225

200226
- name: Get version
201227
id: version
@@ -207,6 +233,6 @@ jobs:
207233
name: Release ${{ steps.version.outputs.VERSION }}
208234
generate_release_notes: true
209235
files: |
210-
step-ca
236+
dist/step-ca_*
211237
env:
212238
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ The most important part of the config is this section
6666

6767
`ca_url` : ACME directory URL of external certificate authority. To get signed certs from InCommon use `https://acme.sectigo.com/v2/InCommonRSAOV`
6868

69-
Many commercial certificate authorities support ACME over external account binding (EAB). You will need to create an EAB token to get HMAC Key and Key ID related to your account.
69+
Most commercial certificate authorities (such as Sectigo) support ACME over external account binding (EAB). You will need to to get your EAB credentials i.e HMAC Key and Key ID related to your account.
7070

7171
```json
7272
"account_email": "admin@example.com",
@@ -76,7 +76,7 @@ Many commercial certificate authorities support ACME over external account bindi
7676

7777
### Starting the ACME server
7878

79-
Upon starting the ACME server it automatically obtains a SSL/TLS certificate from InCommon for itself
79+
Upon starting the ACME server it automatically obtains a SSL/TLS certificate for itself.
8080

8181
```sh
8282
$ ./step-ca ca.json
@@ -192,7 +192,7 @@ We have our certificate signed by InCommon 🎉
192192
193193
### Renewing a certificate
194194
195-
Issuing a certificate is _generally_ not a problem. It's the ability to renew a certificate and reload services post renewal and doing so in a consistent and reliable way is usually the problem. The certificate we obtained above has validity for 13 months! I am using the `--force` flag for renewal only because the default configuration in ACME clients only performs automatic renewal `1 < N < 30` number of days before certificate expiration. This default behaviour can be changed if needed, I think.
195+
Issuing a certificate is _generally_ not a problem in enterprise environments. But the ability to reliably renew certificates and reload services gracefully post renewal is. I am using the `--force` flag for renewal only because the default configuration in ACME clients only performs automatic renewal `1 < N < 30` number of days before certificate expiration.
196196
197197
```sh
198198
$ ./acme.sh --renew --domain myserver.example.com --force

acmeproxy.service

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
[Unit]
2+
Description=ACME Proxy Server (step-ca)
3+
Documentation=https://github.com/esnet/acme-proxy
4+
After=network-online.target
5+
Wants=network-online.target
6+
7+
[Service]
8+
Type=simple
9+
User=acmeproxy
10+
Group=acmeproxy
11+
12+
# Paths
13+
ExecStart=/usr/local/bin/step-ca /etc/acmeproxy/ca.json
14+
WorkingDirectory=/etc/acmeproxy
15+
16+
# Restart behavior
17+
Restart=on-failure
18+
RestartSec=5
19+
StartLimitIntervalSec=60
20+
StartLimitBurst=3
21+
22+
# Security hardening
23+
NoNewPrivileges=yes
24+
ProtectSystem=strict
25+
ProtectHome=yes
26+
PrivateTmp=yes
27+
PrivateDevices=yes
28+
ProtectKernelTunables=yes
29+
ProtectKernelModules=yes
30+
ProtectControlGroups=yes
31+
RestrictSUIDSGID=yes
32+
RestrictNamespaces=yes
33+
34+
# Allow binding to privileged ports (443)
35+
AmbientCapabilities=CAP_NET_BIND_SERVICE
36+
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
37+
38+
# Allow write access to config and database directories
39+
ReadWritePaths=/etc/acmeproxy
40+
41+
# Logging
42+
StandardOutput=journal
43+
StandardError=journal
44+
SyslogIdentifier=acmeproxy
45+
46+
[Install]
47+
WantedBy=multi-user.target

install.sh

Lines changed: 80 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ cat > "$CONFIG_FILE" << 'EOF'
2323
"address": ":443",
2424
"dnsNames": ["acmeproxy.example.com"],
2525
"logger": {
26-
"format": "text"
26+
"format": "json"
2727
},
2828
"db": {
2929
"type": "badgerv2",
@@ -36,10 +36,6 @@ cat > "$CONFIG_FILE" << 'EOF'
3636
"account_email": "",
3737
"eab_kid": "",
3838
"eab_hmac_key": "",
39-
"metrics": {
40-
"enabled": true,
41-
"port": 9123
42-
}
4339
},
4440
"provisioners": [
4541
{
@@ -71,11 +67,79 @@ EOF
7167

7268
echo "Downloading latest release..."
7369
LATEST_RELEASE=$(curl -s "https://api.github.com/repos/${REPO}/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
74-
BINARY_NAME="acme-proxy_${OS}_${ARCH}"
70+
BINARY_NAME="step-ca_${OS}_${ARCH}"
7571
DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${LATEST_RELEASE}/${BINARY_NAME}"
7672

77-
curl -L -o acme-proxy "$DOWNLOAD_URL"
78-
chmod +x acme-proxy
73+
curl -L -o step-ca "$DOWNLOAD_URL"
74+
chmod +x step-ca
75+
76+
echo "Installing binary to /usr/local/bin..."
77+
mv step-ca /usr/local/bin/
78+
79+
echo "Creating acmeproxy service user..."
80+
if ! id acmeproxy >/dev/null 2>&1; then
81+
useradd --system --no-create-home --shell /usr/sbin/nologin acmeproxy
82+
fi
83+
84+
echo "Setting ownership of config directory..."
85+
chown -R acmeproxy:acmeproxy "$CONFIG_DIR"
86+
87+
echo "Installing systemd service..."
88+
cat > /etc/systemd/system/acmeproxy.service << 'EOF'
89+
[Unit]
90+
Description=ACME Proxy Server (step-ca)
91+
Documentation=https://github.com/esnet/acme-proxy
92+
After=network-online.target
93+
Wants=network-online.target
94+
95+
[Service]
96+
Type=simple
97+
User=acmeproxy
98+
Group=acmeproxy
99+
100+
# Paths
101+
ExecStart=/usr/local/bin/step-ca /etc/acmeproxy/ca.json
102+
WorkingDirectory=/etc/acmeproxy
103+
104+
# Restart behavior
105+
Restart=on-failure
106+
RestartSec=5
107+
StartLimitIntervalSec=60
108+
StartLimitBurst=3
109+
110+
# Security hardening
111+
NoNewPrivileges=yes
112+
ProtectSystem=strict
113+
ProtectHome=yes
114+
PrivateTmp=yes
115+
PrivateDevices=yes
116+
ProtectKernelTunables=yes
117+
ProtectKernelModules=yes
118+
ProtectControlGroups=yes
119+
RestrictSUIDSGID=yes
120+
RestrictNamespaces=yes
121+
122+
# Allow binding to privileged ports (443)
123+
AmbientCapabilities=CAP_NET_BIND_SERVICE
124+
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
125+
126+
# Allow write access to config and database directories
127+
ReadWritePaths=/etc/acmeproxy
128+
129+
# Logging
130+
StandardOutput=journal
131+
StandardError=journal
132+
SyslogIdentifier=acmeproxy
133+
134+
[Install]
135+
WantedBy=multi-user.target
136+
EOF
137+
138+
echo "Reloading systemd daemon..."
139+
systemctl daemon-reload
140+
141+
echo "Enabling acmeproxy service..."
142+
systemctl enable acmeproxy
79143

80144
echo ""
81145
echo "Installation complete!"
@@ -85,9 +149,13 @@ echo " 1. Edit ${CONFIG_FILE} and configure:"
85149
echo " - dnsNames: Your ACME proxy hostname"
86150
echo " - ca_url: Your upstream ACME CA URL"
87151
echo " - account_email: Your account email"
88-
echo " - eab_kid: External Account Binding Key ID (if required)"
89-
echo " - eab_hmac_key: External Account Binding HMAC key (if required)"
152+
echo " - eab_kid: External Account Binding Key ID"
153+
echo " - eab_hmac_key: External Account Binding HMAC key"
154+
echo ""
155+
echo " 2. Start the service:"
156+
echo " sudo systemctl start acmeproxy"
90157
echo ""
91-
echo " 2. Start the server:"
92-
echo " step-ca ${CONFIG_FILE}"
158+
echo " 3. Check status:"
159+
echo " sudo systemctl status acmeproxy"
160+
echo " sudo journalctl -u acmeproxy -f"
93161
echo ""

0 commit comments

Comments
 (0)