Oracle Solaris 11.4 on OCI Apache HTTP Server, Solaris PF Firewall and Let's Encrypt HTTPS
Purpose and scope
This runbook provides a repeatable
procedure for deploying an Oracle Solaris 11.4 x86 compute instance on Oracle
Cloud Infrastructure, configuring the system timezone, installing and enabling
Apache HTTP Server 2.4, opening TCP ports 80 and 443 through both OCI network
controls and the Solaris PF firewall, publishing a static webpage, and
obtaining a browser-trusted TLS certificate from Let's Encrypt with acme.sh.
Intended audience
·
OCI administrators and cloud
engineers.
·
Solaris administrators who need
a small public web server.
·
Technical demo and lab
environments where a reproducible Solaris 11.4 configuration is required.
Primary implementation choices
|
Layer |
Choice |
Reason |
|
Compute |
OCI Compute + Oracle Solaris 11.4 x86 |
Native OCI deployment target for this runbook. |
|
Package management |
IPS / pkg |
Native Solaris software lifecycle tooling. |
|
Service management |
SMF / svcadm / svcs |
Native Solaris service control and persistence. |
|
Web server |
Apache HTTP Server 2.4 |
Delivered by Solaris IPS package
web/server/apache-24. |
|
Host firewall |
Solaris PF |
Solaris 11.4 network firewall framework. |
|
TLS certificate |
Let's Encrypt via acme.sh |
Shell-based ACME client with webroot issuance and
automated renewals. |
|
ACME challenge |
HTTP-01 |
Works with an already-running Apache site and
requires TCP/80 reachability. |
Conventions and variables
Replace the following placeholders before
running commands:
|
Variable |
Example |
Meaning |
|
<PUBLIC_IP> |
203.0.113.10 |
OCI public IPv4 address. |
|
<PRIVATE_IP> |
172.16.10.186 |
Solaris VNIC private address. |
|
<ADMIN_PUBLIC_IP> |
198.51.100.25/32 |
Your workstation public IPv4 CIDR. |
|
<FQDN> |
solaris.example.com |
DNS name used for HTTPS. |
|
<EMAIL> |
admin@example.com |
ACME registration/contact email. |
|
Important: For the HTTPS procedure, use an
FQDN that resolves publicly to the OCI public IP. Prefer an OCI Reserved
Public IP so the DNS A record remains stable. |
4 Prerequisites
Before starting, confirm the following:
• An OCI tenancy and compartment where you can create or administer
compute, VCN, subnet, route, public-IP and NSG resources.
• An SSH key pair and administrative access to the Solaris instance.
• A public DNS zone or DNS provider account for the FQDN used by
Let's Encrypt.
• A stable public IPv4 address for the final DNS record; an OCI
Reserved Public IP is preferred for a persistent endpoint.
• Outbound Internet access from Solaris so IPS, acme.sh and the ACME
service can be reached.
• A maintenance window or active fallback SSH session while changing
the Solaris PF rules.
Target architecture
Internet
|
DNS A record:
<FQDN>
|
v
OCI Public IPv4
|
Internet Gateway
|
Public Subnet
|
OCI NSG / SL
+-------------+-------------+
| | |
TCP/22 TCP/80 TCP/443
Admin /32 Public Public
| | |
+-------------+-------------+
|
VNIC / net0
<PRIVATE_IP>
|
Solaris PF Firewall
+-------------+-------------+
| | |
TCP/22 TCP/80 TCP/443
|
v
Apache HTTP 2.4
HTTP/80 HTTPS/443
|
/var/apache2/2.4/htdocs
Traffic path
1. The client resolves <FQDN> to the OCI public IPv4 address.
2. The OCI Internet Gateway and subnet route table provide Internet
routing.
3. The NSG or applicable Security List permits inbound TCP/80 and
TCP/443.
4. OCI maps the public IPv4 address to the instance private IP.
Solaris normally sees only the private address on net0.
5. Solaris PF evaluates the inbound packet and permits the
configured web ports.
6. Apache accepts the request and serves content from the configured
DocumentRoot.
Required OCI network objects
·
VCN.
·
Public subnet.
·
Internet Gateway attached to
the VCN.
·
Route rule 0.0.0.0/0 to the
Internet Gateway.
·
Public IPv4 address on the
Solaris VNIC, preferably Reserved for DNS use.
·
NSG or Security List rules
allowing TCP/80 and TCP/443. SSH should be limited to the administrator's
public /32 where practical.
Deploy Oracle Solaris 11.4 on OCI
Create or select the VCN
1. Open OCI Console and select the target compartment.
2. Open Networking > Virtual Cloud Networks.
3. Create or select a VCN.
4. Create a public subnet for the Solaris instance.
5. Create or confirm an Internet Gateway for the VCN.
6. In the subnet route table, add 0.0.0.0/0 with the Internet
Gateway as the target.
Create the NSG
Create an NSG such as solaris-web-nsg and
add stateful ingress rules:
|
Source |
Protocol |
Destination port |
Use |
|
<ADMIN_PUBLIC_IP>/32 |
TCP |
22 |
SSH administration. |
|
0.0.0.0/0 |
TCP |
80 |
HTTP and Let's Encrypt HTTP-01. |
|
0.0.0.0/0 |
TCP |
443 |
HTTPS. |
For a private lab, TCP/80 and TCP/443 can also be restricted to known source ranges until ACME validation is required
Launch the Solaris instance
1. Open Compute > Instances > Create instance.
2. Select an Oracle Solaris 11.4 x86 image available to your
tenancy. Search in marketplace
3. Choose a compatible compute shape.
4. Select the public subnet and attach solaris-web-nsg.
5. Assign a public IPv4 address.
6. Add your SSH public key.
7. Create the instance and wait until its lifecycle state is
Running.
8. Record the public IP and private IP.
Connect
ssh
-i <PRIVATE_KEY> opc@<PUBLIC_IP>
sudo -i
Verify identity and platform:
whoami
hostname
cat /etc/release
uname -a
Configure timezone to Asia/Kolkata
Check the current timezone
date
nlsadm get-timezone
A new instance can report UTC.
Confirm the target zone exists
nlsadm
list-timezone | grep Kolkata
Expected match:
Asia/Kolkata
If pkg search is degraded
During the validated session, nlsadm
produced a package-search performance warning. Rebuild the IPS search index if
this occurs:
pkg
rebuild-index
Then rerun the timezone list command.
4.4 Set the timezone
nlsadm
set-timezone Asia/Kolkata
Expected command result includes a
successful SMF property update.
Verify
date
nlsadm get-timezone
svcprop -p timezone/localtime svc:/system/timezone:default
Expected values:
<current
date/time> IST
timezone=Asia/Kolkata
Asia/Kolkata
|
Solaris-specific note: Use svc:/system/timezone:default
when querying timezone/localtime. Querying svc:/system/timezone without the
:default instance can fail with a property-group error. |
Verify or install Apache HTTP Server 2.4
Check the IPS publisher
pkg
publisher
On the validated OCI image, the Solaris
publisher was online and pointed to the OCI Solaris support repository.
Check whether Apache is installed
pkg
list web/server/apache-24
If the package is installed, the IFO column
includes i.
Install Apache when missing
pkg
install -nv web/server/apache-24
pkg install web/server/apache-24
The first command previews the IPS
transaction; the second performs the installation.
Check Apache version and syntax
/usr/apache2/2.4/bin/apachectl
-v
/usr/apache2/2.4/bin/apachectl configtest
Required syntax result:
Syntax OK
Check the service state
svcs
-a | grep apache
A fresh system can show:
disabled ...
svc:/network/http:apache24
Enable Apache through SMF
svcadm
enable svc:/network/http:apache24
svcs svc:/network/http:apache24
svcs -xv svc:/network/http:apache24
The service should become online.
Confirm the document root
grep
-n "^DocumentRoot" /etc/apache2/2.4/httpd.conf
ls -la /var/apache2/2.4/htdocs
For the standard Solaris Apache 2.4
package, the working runbook uses:
/var/apache2/2.4/htdocs
Publish a simple webpage
Back up the existing page
cd
/var/apache2/2.4/htdocs
[ -f index.html ] && cp -p index.html index.html.pre-runbook
Create the page
cat
> /var/apache2/2.4/htdocs/index.html <<EOF
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>Oracle Solaris on
OCI</title>
<style>
body { font-family: Arial, Helvetica,
sans-serif;
background: #f4f4f4; margin:
0; padding: 0; }
.container { max-width: 800px;
margin: 80px auto;
background: #fff;
padding: 40px; border-radius: 10px;
box-shadow: 0 4px 15px
rgba(0,0,0,0.15); }
.server-info { margin-top: 25px;
padding: 20px;
background: #f1f1f1;
border-radius: 6px; }
</style>
</head>
<body>
<div class="container">
<h1>Oracle Solaris 11.4 on
OCI</h1>
<p>Welcome to my Oracle Solaris
web server running on Oracle Cloud Infrastructure.</p>
<div
class="server-info">
<h2>Server
Information</h2>
<p><strong>Cloud:</strong> Oracle Cloud
Infrastructure</p>
<p><strong>Operating
System:</strong> Oracle Solaris 11.4</p>
<p><strong>Web
Server:</strong> Apache HTTP Server 2.4</p>
<p><strong>Hostname:</strong> $(hostname)</p>
<p><strong>Timezone:</strong> Asia/Kolkata</p>
<p><strong>Generated:</strong> $(date)</p>
</div>
</div>
</body>
</html>
EOF
Because EOF is unquoted, the hostname and
current date are expanded when the file is created.
Test locally
curl
-I http://localhost/
curl http://localhost/
Expected status:
HTTP/1.1
200 OK
Identify the VNIC address
ipadm
show-addr -p -o ADDROBJ,ADDR
Example from the validated session:
lo0/v4:127.0.0.1/8
net0/v4:172.16.10.43/24
lo0/v6:\:\:1/128
Test using the private IP:
curl
-I http://<PRIVATE_IP>/
Verify port 80 is listening
netstat
-an -P tcp | grep '\.80 '
ps -ef | grep '[h]ttpd'
A listener shown as *.80 confirms Apache is accepting TCP/80 on the host
Configure the Solaris PF firewall for 80 and 443
Oracle Solaris 11.4 uses PF as the host
firewall. The OCI Solaris image validated in this session had the firewall
service online and used a restrictive SSH-only rules file. HTTP failed
externally until an explicit TCP/80 rule was added.
Inspect firewall state
svcs
-xv svc:/network/firewall:default
svcs -a | grep firewall
If the service is online, inspect its
active rules.
Inspect active rules
pfctl
-sr
pfctl -a '*' -sr
The validated SSH-only policy contained the
following effective pattern:
block
return all
pass in proto tcp from any to any port = 22 flags S/SA
pass out all flags S/SA
With no TCP/80 or TCP/443 pass rule,
inbound web traffic is blocked at the Solaris host.
Identify the persistent rules file
svcprop
firewall:default | grep ^firewall
In the validated session:
firewall/rules
astring /etc/firewall/pf_ssh_only.conf
Create a custom rules file
cp
-p /etc/firewall/pf_ssh_only.conf /etc/firewall/pf_web.conf
ls -l /etc/firewall/pf_ssh_only.conf /etc/firewall/pf_web.conf
ls -l/v /etc/firewall/pf_web.conf
Clear the inherited readonly attribute if present
Inspect:
ls
-l/v /etc/firewall/pf_web.conf
If the attribute list contains readonly,
clear only that attribute on the custom copy:
chmod
S-cR /etc/firewall/pf_web.conf
chmod 644 /etc/firewall/pf_web.conf
ls -l/v /etc/firewall/pf_web.conf
Verify that the output now contains
noreadonly. Leave /etc/firewall/pf_ssh_only.conf unchanged.
If you deliberately need to clear every
special attribute on the copy, Solaris also supports chmod S-a file, but the
targeted readonly clear is preferred here.
Allow HTTP and HTTPS in PF
Validate before loading
pfctl
-nf /etc/firewall/pf_web.conf
No output indicates that the syntax check
succeeded. Keep the current SSH session open while changing firewall rules.
Load the rules into the running kernel
pfctl
-f /etc/firewall/pf_web.conf
pfctl -sr | egrep 'port = (22|80|443)'
Expected relevant rules:
pass
in proto tcp from any to any port = 22 flags S/SA
pass in inet proto tcp from any to any port = 80 flags S/SA
pass in inet proto tcp from any to any port = 443 flags S/SA
Make the custom rules file persistent
svccfg
-s svc:/network/firewall:default \
setprop firewall/rules = astring:
/etc/firewall/pf_web.conf
svcadm refresh svc:/network/firewall:default
svcadm restart svc:/network/firewall:default
Verify persistence and service health:
svcprop
-p firewall/rules svc:/network/firewall:default
svcs -xv svc:/network/firewall:default
pfctl -sr | egrep 'port = (22|80|443)'
Expected persistent path:
/etc/firewall/pf_web.conf
Validate HTTP from outside OCI
Check OCI controls
|
Check |
Required state |
|
VNIC |
Public IPv4 address assigned. |
|
Subnet |
Public subnet. |
|
Route |
0.0.0.0/0 points to the Internet Gateway. |
|
Internet Gateway |
Enabled. |
|
NSG/Security List |
TCP/80 allowed from the required source. |
|
Solaris PF |
TCP/80 pass rule loaded. |
|
Apache |
Port 80 listening and HTTP 200 locally. |
Test from Windows
Test-NetConnection
<PUBLIC_IP> -Port 80
curl.exe -v http://<PUBLIC_IP>/
The validated deployment successfully
displayed the page in a browser after the PF TCP/80 rule was added.
Packet-level isolation when needed
If local HTTP works but the public IP still
fails, run Solaris packet capture while testing from an external client:
snoop
-d net0 port 80
If no inbound SYN reaches net0, inspect OCI
routing, the public IP association, NSG membership, and Security Lists. If
packets reach net0 but no response is sent, inspect PF and Apache.
Prepare DNS and the public IP for HTTPS
Prefer a Reserved Public IP
For a long-lived TLS endpoint, assign a
Reserved Public IPv4 address to the Solaris VNIC. This avoids an FQDN pointing
to a different address after an instance or VNIC lifecycle change.
Create a DNS A record
At your authoritative DNS provider create:
|
Type |
Name |
Value |
|
A |
solaris (or chosen host label) |
<PUBLIC_IP> |
The resulting FQDN might be:
solaris.example.com
Verify public DNS before ACME
getent
hosts <FQDN>
curl -I http://<FQDN>/
The name must resolve to the OCI public IP
and HTTP must be reachable publicly.
Why TCP/80 stays open
Let's Encrypt HTTP-01 validation starts on
TCP/80 and retrieves a token under /.well-known/acme-challenge/. Keep TCP/80
reachable for issuance and renewal. After HTTPS is configured, port 80 can
redirect ordinary requests to HTTPS.
Install and configure acme.sh
This runbook uses acme.sh in webroot mode.
Webroot mode is appropriate because Apache is already serving the site and can
expose the ACME challenge file without stopping the web server.
Define working variables
DOMAIN="<FQDN>"
EMAIL="<EMAIL>"
WEBROOT="/var/apache2/2.4/htdocs"
SSL_DIR="/etc/apache2/2.4/ssl"
export DOMAIN EMAIL WEBROOT SSL_DIR
Verify dependencies
which
curl
which openssl
which crontab
openssl version
Resolve any missing tool before continuing.
pkg install archiver/gnu-tar
Install acme.sh
curl
https://get.acme.sh | sh -s email="$EMAIL"
The installer normally places the client
under the invoking user's ~/.acme.sh directory and creates a renewal cron
entry.
For this runbook, installation is performed
as root, so the expected path is:
/root/.acme.sh/acme.sh
Verify acme.sh
/root/.acme.sh/acme.sh
--version
/root/.acme.sh/acme.sh --help | head
Select Let's Encrypt explicitly
/root/.acme.sh/acme.sh --set-default-ca --server letsencrypt
acme.sh supports multiple certificate
authorities; this command explicitly selects Let's Encrypt.
Validate the HTTP-01 challenge path
Create the challenge directory
mkdir
-p "$WEBROOT/.well-known/acme-challenge"
echo "ACME test OK" >
"$WEBROOT/.well-known/acme-challenge/test.txt"
Test locally by hostname
curl
"http://$DOMAIN/.well-known/acme-challenge/test.txt"
Expected:
ACME
test OK
Test from an external network
Open the following URL from a device
outside the OCI VCN:
http://<FQDN>/.well-known/acme-challenge/test.txt
Do not request a production certificate
until this URL works from the public Internet.
Issue the Let's Encrypt certificate
Optional staging test
Before production issuance, a staging test
is useful when you are still validating DNS, webroot permissions, or redirects.
With current acme.sh, use the Let's Encrypt staging CA alias explicitly:
/root/.acme.sh/acme.sh --issue
--server letsencrypt_test -d
"$DOMAIN" -w "$WEBROOT"
Staging certificates are not
browser-trusted. After a successful staging test, issue a production
certificate.
Issue the production certificate
/root/.acme.sh/acme.sh --issue
--server letsencrypt -d
"$DOMAIN" -w "$WEBROOT"
acme.sh defaults to an ECC certificate
unless a different key type is requested.
List managed certificates
/root/.acme.sh/acme.sh
--list
Install the certificate into stable Apache TLS paths
Do not configure Apache to read certificate
files directly from the internal ~/.acme.sh hierarchy. Use acme.sh
--install-cert to copy the key and full chain to stable production paths and
record the Apache reload command.
Create the TLS directory and files
mkdir
-p "$SSL_DIR"
chmod 700 "$SSL_DIR"
touch "$SSL_DIR/$DOMAIN.key"
touch "$SSL_DIR/$DOMAIN.fullchain.pem"
chmod 600 "$SSL_DIR/$DOMAIN.key"
chmod 644 "$SSL_DIR/$DOMAIN.fullchain.pem"
Install the certificate
/root/.acme.sh/acme.sh
\
--install-cert \
-d "$DOMAIN" \
--key-file
"$SSL_DIR/$DOMAIN.key" \
--fullchain-file
"$SSL_DIR/$DOMAIN.fullchain.pem" \
--reloadcmd "svcadm restart
svc:/network/http:apache24"
This also records the reload action for
future renewals.
Inspect the certificate
openssl
x509 \
-in
"$SSL_DIR/$DOMAIN.fullchain.pem" \
-noout -subject -issuer -dates
Enable SSL/TLS in Apache
Confirm the SSL module state
/usr/apache2/2.4/bin/httpd
-M | grep ssl
grep -n 'ssl_module' /etc/apache2/2.4/httpd.conf
If ssl_module is already listed by httpd
-M, continue. If the httpd.conf contains a commented LoadModule ssl_module
line, back up the file and uncomment that existing line rather than inventing a
module path.
Back up Apache configuration
cp
-p /etc/apache2/2.4/httpd.conf
/etc/apache2/2.4/httpd.conf.pre-https
Enable the packaged ssl_module when needed
Edit:
vi
/etc/apache2/2.4/httpd.conf
Find the existing ssl_module LoadModule
directive and remove the leading #. Then validate:
/usr/apache2/2.4/bin/apachectl
configtest
/usr/apache2/2.4/bin/httpd -M | grep ssl
Required syntax result:
Syntax
OK
Confirm conf.d inclusion
grep -n 'Include' /etc/apache2/2.4/httpd.conf
If the packaged configuration already
includes /etc/apache2/2.4/conf.d/*.conf, use that directory. If it does not,
add an IncludeOptional directive only after reviewing the local httpd.conf
layout.
Check for an existing port 443 listener directive
grep
-R "^[[:space:]]*Listen[[:space:]]\+443" /etc/apache2/2.4 2>/dev/null
Avoid adding a duplicate Listen 443
directive.
Create the HTTPS VirtualHost
cat
> /etc/apache2/2.4/conf.d/solaris-web-ssl.conf <<EOF
Listen 443
<VirtualHost *:443>
ServerName ${DOMAIN}
DocumentRoot "${WEBROOT}"
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3 -TLSv1
-TLSv1.1
SSLCertificateFile
"${SSL_DIR}/${DOMAIN}.fullchain.pem"
SSLCertificateKeyFile
"${SSL_DIR}/${DOMAIN}.key"
ErrorLog
"/var/apache2/2.4/logs/${DOMAIN}-ssl-error.log"
CustomLog
"/var/apache2/2.4/logs/${DOMAIN}-ssl-access.log" combined
</VirtualHost>
EOF
|
If Listen 443 already exists: Remove the Listen 443
line from this custom file and keep the existing listener directive. Apache
must have only the listener configuration that your local package layout
expects. |
Validate and restart Apache
/usr/apache2/2.4/bin/apachectl
configtest
svcadm restart svc:/network/http:apache24
svcs -xv svc:/network/http:apache24
Do not continue if configtest reports an
error.
Verify port 443
netstat
-an -P tcp | egrep '\.(80|443) '
pfctl -sr | egrep 'port = (22|80|443)'
You should see listeners on both web ports
and PF pass rules for 80 and 443.
Validate HTTPS
Test with curl
curl
-I "https://$DOMAIN/"
Expected status is HTTP 200 or another
intentional application response without a TLS trust error.
Inspect the certificate presented by Apache
openssl
s_client \
-connect "${DOMAIN}:443" \
-servername "${DOMAIN}" \
</dev/null 2>/dev/null | \
openssl x509 -noout -subject -issuer -dates
Test from a browser
Open:
https://<FQDN>/
Verify the certificate is trusted and its
subject/SAN contains the requested FQDN.
Redirect HTTP to HTTPS
Enable the redirect only after HTTPS is
working. TCP/80 remains open because Let's Encrypt HTTP-01 begins on port 80
and can follow appropriate redirects.
Create an HTTP VirtualHost
cat
> /etc/apache2/2.4/conf.d/solaris-web-http.conf <<EOF
<VirtualHost *:80>
ServerName ${DOMAIN}
DocumentRoot "${WEBROOT}"
Redirect permanent /
https://${DOMAIN}/
</VirtualHost>
EOF
Validate and restart
/usr/apache2/2.4/bin/apachectl
configtest
svcadm restart svc:/network/http:apache24
svcs -xv apache24
Verify the redirect
curl
-I "http://$DOMAIN/"
Expected response is a 301/302 redirect
with a Location header pointing to https://<FQDN>/.
Automatic certificate renewal
Confirm the cron entry
crontab
-l | grep acme.sh
The acme.sh installer normally creates a
daily cron job that checks certificate renewal state.
Confirm Solaris cron is online
svcs
svc:/system/cron:default
If required:
svcadm
enable svc:/system/cron:default
Run the ACME cron handler manually
/root/.acme.sh/acme.sh --cron
--home /root/.acme.sh
A normal run can report that the
certificate is not due for renewal.
Verify reload integration
Because --install-cert stored the command
svcadm restart svc:/network/http:apache24, a successful renewal can copy the
updated certificate to the production path and restart Apache so the new
certificate is presented.
Persistence and reboot validation
Pre-reboot checks
date
nlsadm get-timezone
svcs apache24
svcs network/firewall
svcprop -p firewall/rules svc:/network/firewall:default
pfctl -sr | egrep 'port = (22|80|443)'
netstat -an -P tcp | egrep '\.(80|443) '
Reboot
init
6
Reconnect after the instance is available.
Post-reboot checks
date
nlsadm get-timezone
svcs apache24
svcs network/firewall
svcprop -p firewall/rules svc:/network/firewall:default
pfctl -sr | egrep 'port = (22|80|443)'
netstat -an -P tcp | egrep '\.(80|443) '
curl -I "https://<FQDN>/"
This validates timezone, SMF service
enablement, PF persistence, Apache listeners, and TLS after a full reboot.
Final health-check command set
Run as root after deployment:
echo
"===== OS ====="
cat /etc/release | head -5
echo
echo "===== TIME ====="
date
echo
echo "===== TIMEZONE ====="
nlsadm get-timezone
echo
echo "===== NETWORK ====="
ipadm show-addr -p -o ADDROBJ,ADDR
echo
echo "===== APACHE PACKAGE ====="
pkg list web/server/apache-24
echo
echo "===== APACHE ====="
svcs apache24
echo
echo "===== FIREWALL ====="
svcs network/firewall
echo
echo "===== PF CONFIG FILE ====="
svcprop -p firewall/rules svc:/network/firewall:default
echo
echo "===== FIREWALL RULES ====="
pfctl -sr | egrep 'port = (22|80|443)'
echo
echo "===== LISTENERS ====="
netstat -an -P tcp | egrep '\.(80|443) '
echo
echo "===== APACHE CONFIG ====="
/usr/apache2/2.4/bin/apachectl configtest
echo
echo "===== HTTP ====="
curl -I "http://<FQDN>/"
echo
echo "===== HTTPS ====="
curl -I "https://<FQDN>/"
echo
echo "===== ACME ====="
/root/.acme.sh/acme.sh --list
echo
echo "===== ACME CRON ====="
crontab -l | grep acme.sh
Troubleshooting
Apache is disabled
svcs
-a | grep apache
svcadm enable svc:/network/http:apache24
svcs -xv svc:/network/http:apache24
Apache enters maintenance
svcs
-xv svc:/network/http:apache24
/usr/apache2/2.4/bin/apachectl configtest
tail -100 /var/apache2/2.4/logs/error_log
Correct the underlying problem, then:
svcadm
clear svc:/network/http:apache24
HTTP works locally but not through the public IP
1. Confirm curl http://<PRIVATE_IP>/ returns a response.
2. Confirm netstat shows *.80 LISTEN.
3. Confirm pfctl -sr contains a TCP/80 pass rule.
4. Confirm the VNIC is attached to the intended NSG.
5. Confirm the NSG or Security List permits TCP/80.
6. Confirm the subnet route table has 0.0.0.0/0 to an enabled
Internet Gateway.
7. Confirm the public IP is assigned to the private IP used by the
VNIC.
8. Run snoop -d net0 port 80 while testing externally.
Editing pf_web.conf returns 'Insufficient privileges'
Check both POSIX permissions and Solaris
special attributes:
ls
-l /etc/firewall/pf_web.conf
ls -l/v /etc/firewall/pf_web.conf
If normal permissions are writable but the
attribute list contains readonly:
chmod
S-cR /etc/firewall/pf_web.conf
chmod 644 /etc/firewall/pf_web.conf
This exact condition was encountered in the
validated deployment.
PF rule syntax failure
pfctl
-nf /etc/firewall/pf_web.conf
tail -100 /var/svc/log/network-firewall:default.log
Do not restart the firewall service until
the rules file passes pfctl -nf.
Port 443 does not listen
/usr/apache2/2.4/bin/apachectl
configtest
/usr/apache2/2.4/bin/httpd -M | grep ssl
grep -R "^[[:space:]]*Listen[[:space:]]\+443" /etc/apache2/2.4
2>/dev/null
svcs -xv apache24
tail -100 /var/apache2/2.4/logs/error_log
Check for an unloaded ssl_module, duplicate
Listen 443 directives, invalid certificate paths, or unreadable key files.
Let's Encrypt HTTP-01 fails
1. Confirm <FQDN> resolves publicly to the OCI public IP.
2. Confirm http://<FQDN>/.well-known/acme-challenge/test.txt
is reachable externally.
3. Confirm TCP/80 is allowed by the OCI NSG/Security List.
4. Confirm TCP/80 is allowed by Solaris PF.
5. Confirm Apache is serving the expected WEBROOT.
6. Check for redirects that route the ACME path to an unrelated
host.
7. Use Let's Encrypt staging while troubleshooting to avoid
production rate-limit pressure.
Certificate renews but browser still shows the old
certificate
openssl
x509 -in "$SSL_DIR/$DOMAIN.fullchain.pem" -noout -dates
/root/.acme.sh/acme.sh --list
svcadm restart svc:/network/http:apache24
Confirm that --install-cert was configured
with the production paths and the Solaris SMF reload command.
Rollback procedure
Roll back Apache HTTPS configuration
mv
/etc/apache2/2.4/conf.d/solaris-web-ssl.conf
/etc/apache2/2.4/conf.d/solaris-web-ssl.conf.disabled
mv /etc/apache2/2.4/conf.d/solaris-web-http.conf
/etc/apache2/2.4/conf.d/solaris-web-http.conf.disabled
/usr/apache2/2.4/bin/apachectl configtest
svcadm restart svc:/network/http:apache24
If you changed httpd.conf to enable
ssl_module and must fully revert, restore the recorded pre-HTTPS backup after
reviewing any later changes.
Roll back PF to the original SSH-only policy
|
Warning: This removes web access on TCP/80 and TCP/443. Keep
an active SSH session and confirm that the original SSH rule exists before
applying the rollback. |
pfctl
-nf /etc/firewall/pf_ssh_only.conf
pfctl -f /etc/firewall/pf_ssh_only.conf
svccfg -s svc:/network/firewall:default \
setprop firewall/rules = astring:
/etc/firewall/pf_ssh_only.conf
svcadm refresh svc:/network/firewall:default
svcadm restart svc:/network/firewall:default
svcprop -p firewall/rules svc:/network/firewall:default
pfctl -sr
Security recommendations
·
Restrict OCI TCP/22 to the
administrator's trusted public CIDR rather than 0.0.0.0/0.
·
Keep the Solaris PF
default-deny policy and add only required inbound services.
·
Protect the TLS private key
with root ownership and mode 600.
·
Retain TCP/80 for HTTP-01
validation and redirect normal HTTP requests to HTTPS.
·
Use an OCI Reserved Public IP
when DNS and TLS depend on a stable endpoint.
·
Keep Solaris SRUs and Apache
packages current through approved maintenance procedures.
·
Review /var/apache2/2.4/logs
and the PF service log during operational monitoring.
·
Test ACME changes against Let's
Encrypt staging before repeated production issuance attempts.
Deployment checklist
☐ OCI public subnet is
routed to an enabled Internet Gateway.
☐ Solaris VNIC has the
intended public IPv4 address.
☐ NSG permits TCP/22 from
the administrator /32.
☐ NSG permits TCP/80 and
TCP/443 from the required sources.
☐ Solaris reports
timezone=Asia/Kolkata.
☐ Apache package
web/server/apache-24 is installed.
☐ svc:/network/http:apache24
is online.
☐ Static page returns HTTP
200 from localhost and the private IP.
☐ Solaris firewall service
is online.
☐ PF persistent file is
/etc/firewall/pf_web.conf.
☐ PF contains TCP/22,
TCP/80 and TCP/443 pass rules.
☐ Public HTTP access
succeeds.
☐ DNS A record for
<FQDN> resolves to the OCI public IP.
☐ ACME challenge test file
is reachable from the public Internet.
☐ Let's Encrypt
certificate has been issued.
☐ Certificate is installed
under /etc/apache2/2.4/ssl.
☐ Apache ssl_module is
loaded.
☐ Apache listens on
TCP/443.
☐ HTTPS returns a trusted
certificate.
☐ HTTP redirects to HTTPS.
☐ acme.sh renewal cron
entry exists.
☐ Post-reboot validation
succeeds.
Official references
Oracle Solaris 11.4 - Apache HTTP Server
installation and SMF enablement: https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/config-app-dev/introduction-setting-up-application-development-environment-oracle-solaris-11.html
Oracle Solaris 11.4 - Apache configuration
paths: https://docs.oracle.com/cd/E37838_01/html/E60982/apache-config.html
Oracle Solaris 11.4 - PF firewall
configuration: https://docs.oracle.com/cd/E37838_01/html/E60993/pftask-conf.html
Oracle Solaris 11.4 - PF rules file and
firewall/rules SMF property: https://docs.oracle.com/cd/E37838_01/html/E60993/pfovw-files.html
Oracle Solaris 11.4 - PF administration
with pfctl: https://docs.oracle.com/cd/E37838_01/html/E60993/pftask-pfctl.html
Oracle Solaris 11.4 - ZFS special file
attributes: https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/secure-files/displaying-and-changing-zfs-file-attributes.html
Let's Encrypt - Challenge Types / HTTP-01: https://letsencrypt.org/docs/challenge-types/
Let's Encrypt - Keep Port 80 Open: https://letsencrypt.org/docs/allow-port-80/
acme.sh official project: https://github.com/acmesh-official/acme.sh
Validated session notes
|
Observation |
Validated result |
|
Timezone before change |
UTC |
|
Timezone after change |
Asia/Kolkata / IST |
|
Apache package |
web/server/apache-24 already installed |
|
Apache version |
2.4.67 |
|
Apache config test |
Syntax OK |
|
Apache SMF |
svc:/network/http:apache24 online |
|
Private address |
172.16.10.186/24 on net0 |
|
Local HTTP |
HTTP/1.1 200 OK |
|
Firewall SMF |
svc:/network/firewall:default online |
|
Original persistent rules |
/etc/firewall/pf_ssh_only.conf |
|
Original inbound policy |
SSH allowed; HTTP blocked |
|
Custom rules file |
/etc/firewall/pf_web.conf |
|
Special attribute issue |
Copy inherited readonly; normal chmod alone did not
permit writes |
|
Resolved PF policy |
TCP/22 and TCP/80 verified; runbook extends policy
to TCP/443 |
|
External HTTP |
Successfully displayed through the OCI public IP |
Comments
Post a Comment