mirror of
https://github.com/home-assistant/iOS.git
synced 2026-06-26 03:02:18 -05:00
<!-- Thank you for submitting a Pull Request and helping to improve Home Assistant. Please complete the following sections to help the processing and review of your changes. Please do not delete anything from this template. --> ## Summary <!-- Provide a brief summary of the changes you have made and most importantly what they aim to achieve --> This PR adds experimental mTLS support, it does not work properly on older iOS versions neither on Apple Watch yet. Mac Catalyst TBD how well it works. This PR modifies: - WebView connection - Alamofire token exchange - Webhook - Websocket (pending HAKit PR) Pending implementation/check - [ ] Apple Watch - [ ] Background usage (widgets, shortcuts, notifications) - [x] Mac Catalyst - [ ] Background refresh - [x] [HAKit PR](https://github.com/home-assistant/HAKit/pull/92/changes#diff-1ccd1173574d21603ee9aab6340ee5c825e62b94f112362346a931b10463594b) ## Screenshots <!-- If this is a user-facing change not in the frontend, please include screenshots in light and dark mode. --> Happy path: https://github.com/user-attachments/assets/8d41d871-8cb8-4498-8e09-24716fff6971 ## Link to pull request in Documentation repository <!-- Pull requests that add, change or remove functionality must have a corresponding pull request in the Companion App Documentation repository (https://github.com/home-assistant/companion.home-assistant). Please add the number of this pull request after the "#" --> Documentation: home-assistant/companion.home-assistant# ## Any other notes <!-- If there is any other information of note, like if this Pull Request is part of a bigger change, please include it here. -->
176 lines
6.1 KiB
Markdown
176 lines
6.1 KiB
Markdown
# mTLS (Mutual TLS) Support
|
|
|
|
> ⚠️ **EXPERIMENTAL FEATURE**
|
|
>
|
|
> This feature is experimental and may change or be removed in future versions.
|
|
> Use at your own risk and report any issues you encounter.
|
|
|
|
## What is mTLS?
|
|
|
|
Mutual TLS (mTLS) is a security protocol where both the client and server authenticate each other using certificates. Unlike standard TLS where only the server presents a certificate, mTLS requires the client to also present a valid certificate.
|
|
|
|
This is commonly used to:
|
|
- Secure Home Assistant access behind a reverse proxy (nginx, Traefik, etc.)
|
|
- Add an extra layer of authentication beyond username/password
|
|
- Restrict access to devices with trusted certificates only
|
|
|
|
## How It Works
|
|
|
|
```
|
|
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
│ iOS App │ mTLS │ Nginx │ HTTP │ Home │
|
|
│ │◄───────►│ (Proxy) │◄───────►│ Assistant │
|
|
│ + Client Cert│ │ + Server Cert│ │ │
|
|
└──────────────┘ └──────────────┘ └──────────────┘
|
|
```
|
|
|
|
1. **Server Certificate**: The reverse proxy (e.g., nginx) presents its SSL certificate
|
|
2. **Client Certificate**: The iOS app presents its client certificate (.p12 file)
|
|
3. **Mutual Verification**: Both sides verify each other's certificates
|
|
4. **Secure Connection**: Once verified, traffic flows through encrypted tunnel
|
|
|
|
## Setup Requirements
|
|
|
|
### 1. Generate Certificates
|
|
|
|
You'll need:
|
|
- A Certificate Authority (CA) certificate
|
|
- A server certificate signed by the CA
|
|
- A client certificate signed by the CA (exported as .p12)
|
|
|
|
Example using OpenSSL:
|
|
|
|
```bash
|
|
# Create CA
|
|
openssl genrsa -out ca.key 4096
|
|
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj "/CN=My Home CA"
|
|
|
|
# Create Server Certificate
|
|
openssl genrsa -out server.key 2048
|
|
openssl req -new -key server.key -out server.csr -subj "/CN=homeassistant.local"
|
|
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
|
|
|
|
# Create Client Certificate
|
|
openssl genrsa -out client.key 2048
|
|
openssl req -new -key client.key -out client.csr -subj "/CN=ios-app"
|
|
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt
|
|
|
|
# Export client certificate as .p12 (for iOS)
|
|
openssl pkcs12 -export -out client.p12 -inkey client.key -in client.crt -certfile ca.crt -password pass:your_password
|
|
```
|
|
|
|
### 2. Configure Reverse Proxy (nginx example)
|
|
|
|
```nginx
|
|
server {
|
|
listen 8443 ssl;
|
|
server_name homeassistant.local;
|
|
|
|
# Server certificate
|
|
ssl_certificate /path/to/server.crt;
|
|
ssl_certificate_key /path/to/server.key;
|
|
|
|
# mTLS - require client certificate
|
|
ssl_client_certificate /path/to/ca.crt;
|
|
ssl_verify_client on;
|
|
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
|
|
location / {
|
|
proxy_pass http://homeassistant:8123;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
|
|
# WebSocket support
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. Transfer Client Certificate to iOS
|
|
|
|
Transfer the `.p12` file to your iOS device via:
|
|
- AirDrop
|
|
- iCloud Drive
|
|
- Email attachment
|
|
- Any file sharing method
|
|
|
|
## Using mTLS in the App
|
|
|
|
### During Onboarding
|
|
|
|
1. Enter your Home Assistant URL (e.g., `https://homeassistant.local:8443`)
|
|
2. If the server requires mTLS, you'll see a prompt to import a client certificate
|
|
3. Tap "Import Certificate" and select your `.p12` file
|
|
4. Enter the password used when creating the .p12 file
|
|
5. Continue with normal login flow
|
|
|
|
### Certificate Storage
|
|
|
|
- Certificates are stored securely in the iOS Keychain
|
|
- The certificate reference is saved with your server configuration
|
|
- Certificates persist across app reinstalls (stored in Keychain)
|
|
|
|
## Troubleshooting
|
|
|
|
### "SSL Handshake Failed" or Connection Errors
|
|
|
|
- Verify your client certificate is signed by the same CA configured on the server
|
|
- Check that the .p12 file includes the full certificate chain
|
|
- Ensure the certificate hasn't expired
|
|
|
|
### "Certificate Required" but No Prompt
|
|
|
|
- Make sure you're using HTTPS, not HTTP
|
|
- Verify the server is actually requiring client certificates (`ssl_verify_client on`)
|
|
|
|
### WebSocket Connection Issues
|
|
|
|
- Check that your proxy configuration supports WebSocket upgrade
|
|
- Verify the proxy passes through the client certificate for WebSocket connections
|
|
|
|
### Webhook Errors
|
|
|
|
- Webhooks use a separate connection that also requires the client certificate
|
|
- If webhooks fail with 400/401 errors, verify the certificate is properly configured
|
|
|
|
## Technical Details
|
|
|
|
The app handles mTLS at three different layers:
|
|
|
|
1. **Alamofire (HTTP requests)**: Uses `ClientCertificateSessionDelegate` to provide client certificates for API calls
|
|
|
|
2. **HAKit/Starscream (WebSocket)**: Uses `FoundationTransport` with custom SSL stream configuration for the WebSocket connection to Home Assistant
|
|
|
|
3. **WebhookManager (Background uploads)**: Uses `ConnectionInfo.evaluate()` to handle client certificate challenges for webhook requests
|
|
|
|
## Limitations
|
|
|
|
- **watchOS**: mTLS is not supported on Apple Watch due to platform limitations
|
|
- **Local Push**: May not work with mTLS configurations
|
|
- **Siri/Shortcuts**: May have limited functionality with mTLS
|
|
|
|
## Security Considerations
|
|
|
|
- Keep your `.p12` file and password secure
|
|
- Use strong passwords when exporting certificates
|
|
- Rotate certificates periodically
|
|
- Revoke compromised certificates immediately by updating your CA
|
|
|
|
---
|
|
|
|
## Need Help?
|
|
|
|
If you encounter issues with mTLS:
|
|
1. Check the app logs (Settings → Debug → Export Logs)
|
|
2. Verify your certificate chain with: `openssl verify -CAfile ca.crt client.crt`
|
|
3. Test your nginx configuration: `nginx -t`
|
|
|
|
---
|
|
|
|
*This documentation is for the experimental mTLS feature in the Home Assistant iOS app.*
|