Apache TomEE - Hardened Jakarta EE Application Server
بواسطة Lynxroute
Apache TomEE 10.2.0 - CIS Level 1 hardened Jakarta EE server on Ubuntu 24.04, SBOM + CIS
What is Apache TomEE
Apache TomEE is Apache Tomcat with the Jakarta EE stack assembled on top of it. You get the servlet container you already know, plus the enterprise APIs that Tomcat alone does not provide: Enterprise Beans for transactional business logic, Contexts and Dependency Injection for wiring, Persistence for mapping objects to relational data, RESTful and SOAP Web Services, Messaging, Faces for server-side UI, and Bean Validation. Applications deploy as ordinary WAR or EAR archives dropped into the webapps directory. This image ships the Plume distribution - the full profile, built on EclipseLink for Persistence and Mojarra for Faces. It is one JVM process, with no external database, cache tier or container runtime to operate alongside it.
Why self-host Apache TomEE
An application server holds your business logic, data connections, session state and credentials. Self-hosting keeps all of that inside your own network boundary and jurisdiction, which matters directly for GDPR and sector rules on personal data. It also keeps you on portable, standards-based APIs: an application written to the Jakarta EE specifications can move between compliant servers.
What this VM image adds
Security hardening:
- HTTP connector bound to loopback - TomEE listens on 127.0.0.1:8080 only; nginx terminates TLS on 443 and reverse-proxies to it, so the application server is never directly reachable from the network
- Manager and Host-Manager never publicly exposed - two independent controls: nginx returns 403 for both paths at the perimeter, and Tomcat's own address valve admits 127.0.0.0/8 only. Administrators reach them over an SSH tunnel
- Per-instance admin password - generated on your own VM at first boot, so no two deployments share a credential and nothing is baked into the image
- No sample or example applications - the build asserts their absence rather than assuming it
- Only the required listeners enabled - the AJP and secondary HTTPS connectors stay disabled, and the build fails if a future release enables either
- Bundled message broker opens no port - the embedded Messaging provider is available to applications but binds no TCP listener until you configure one
- JVM heap sized from your VM - calculated from the machine's real memory at first boot instead of a fixed value that is wrong on most VM sizes
- CVE scan - every image is scanned for vulnerabilities with Trivy before release
- UFW firewall - only 443, 80 (redirect and certificate renewal) and SSH on 22 are open
- fail2ban - SSH brute-force protection
- AppArmor - mandatory access control
OS hardening (CIS Level 1):
- CIS Level 1 hardened - CIS Ubuntu 24.04 LTS Level 1 Benchmark via ansible-lockdown
- auditd - system call auditing for critical paths
- SSH hardening - PasswordAuthentication disabled, key-only access
- Kernel hardening - SYN cookies, ASLR, rp_filter, TCP BBR
- /tmp as tmpfs - nosuid, nodev, noexec
- Azure IMDS endpoints - egress rules pre-configured (169.254.169.254, 168.63.129.16)
Compliance artifacts (inside the VM):
- SBOM - CycloneDX 1.6 at /etc/lynxroute/sbom.json
- CIS Conformance Report - OpenSCAP HTML at /etc/lynxroute/cis-report.html
- Tailored CIS profile - /usr/share/doc/lynxroute/CIS_TAILORED_PROFILE.md
- Jakarta EE verification application - a small sample at /usr/share/lynxroute/tomee-sample.war, shipped but not deployed, so you can prove the enterprise stack works on your own instance in one command
Quick Start
- Deploy the VM (Standard_D2s_v3 or larger recommended)
- SSH: ssh -i key.pem <username>@<PUBLIC_IP> (username set during VM creation, default: azureuser)
- Check status: the login banner shows the version, service state and the URL to open
- Read the generated credentials: sudo cat /root/tomee-credentials.txt
- Open https://<PUBLIC_IP>/, accept the self-signed certificate, then replace it: sudo certbot --nginx -d yourdomain.com
- Deploy your application by copying a .war into /opt/tomee/webapps/
The Manager application is deliberately unreachable from the internet; use the SSH tunnel command in the credentials file to administer the server.