netscaler-certbot-hook 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- netscaler_certbot_hook-1.0.0/CHANGELOG.md +162 -0
- netscaler_certbot_hook-1.0.0/LICENSE +21 -0
- netscaler_certbot_hook-1.0.0/MANIFEST.in +6 -0
- netscaler_certbot_hook-1.0.0/PKG-INFO +462 -0
- netscaler_certbot_hook-1.0.0/README.md +429 -0
- netscaler_certbot_hook-1.0.0/pyproject.toml +52 -0
- netscaler_certbot_hook-1.0.0/requirements.txt +8 -0
- netscaler_certbot_hook-1.0.0/setup.cfg +4 -0
- netscaler_certbot_hook-1.0.0/src/netscaler_certbot_hook/__init__.py +29 -0
- netscaler_certbot_hook-1.0.0/src/netscaler_certbot_hook/__main__.py +13 -0
- netscaler_certbot_hook-1.0.0/src/netscaler_certbot_hook/cli.py +639 -0
- netscaler_certbot_hook-1.0.0/src/netscaler_certbot_hook/nitro.py +333 -0
- netscaler_certbot_hook-1.0.0/src/netscaler_certbot_hook.egg-info/PKG-INFO +462 -0
- netscaler_certbot_hook-1.0.0/src/netscaler_certbot_hook.egg-info/SOURCES.txt +16 -0
- netscaler_certbot_hook-1.0.0/src/netscaler_certbot_hook.egg-info/dependency_links.txt +1 -0
- netscaler_certbot_hook-1.0.0/src/netscaler_certbot_hook.egg-info/entry_points.txt +2 -0
- netscaler_certbot_hook-1.0.0/src/netscaler_certbot_hook.egg-info/requires.txt +2 -0
- netscaler_certbot_hook-1.0.0/src/netscaler_certbot_hook.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.0] - 2025-01-11
|
|
9
|
+
|
|
10
|
+
### Major Refactoring - Production Ready Release
|
|
11
|
+
|
|
12
|
+
This release represents a complete overhaul of the codebase, transforming it from a working script into a professional, production-ready Python application with comprehensive documentation, error handling, and modern development practices.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
#### Code Structure & Quality
|
|
17
|
+
- Complete refactoring into 14 well-structured functions
|
|
18
|
+
- `parse_arguments()` - Dedicated argument parsing
|
|
19
|
+
- `get_config()` - Configuration building with full validation
|
|
20
|
+
- `get_certificate_serial()` - Certificate parsing abstraction
|
|
21
|
+
- `process_chain_certificate()` - Chain certificate handling
|
|
22
|
+
- `process_certificate()` - Main certificate processing
|
|
23
|
+
- `install_or_update_certificate()` - Unified install/update logic
|
|
24
|
+
- `setup_logging()` - Configurable logging setup
|
|
25
|
+
- Proper `main()` function with `if __name__ == '__main__'` pattern
|
|
26
|
+
|
|
27
|
+
#### Logging Framework
|
|
28
|
+
- Python `logging` module integration (replaced all `print()` statements)
|
|
29
|
+
- `--verbose` flag for DEBUG level output
|
|
30
|
+
- `--quiet` flag for ERROR-only output
|
|
31
|
+
- Structured log messages with proper formatting
|
|
32
|
+
- Debug information for troubleshooting
|
|
33
|
+
- Cron-friendly logging options
|
|
34
|
+
|
|
35
|
+
#### Error Handling
|
|
36
|
+
- Specific exception types (no more bare `except:` blocks)
|
|
37
|
+
- `requests.exceptions.Timeout` - Request timeout handling
|
|
38
|
+
- `requests.exceptions.ConnectionError` - Connection failure handling
|
|
39
|
+
- `requests.exceptions.HTTPError` - HTTP error handling
|
|
40
|
+
- `requests.exceptions.RequestException` - General request errors
|
|
41
|
+
- File existence validation before operations
|
|
42
|
+
- URL format validation
|
|
43
|
+
- Empty credentials validation
|
|
44
|
+
- Certificate format validation
|
|
45
|
+
- 30-second timeout for all NITRO API requests
|
|
46
|
+
|
|
47
|
+
#### Documentation
|
|
48
|
+
- Comprehensive module-level docstrings (PEP 257)
|
|
49
|
+
- Google/NumPy style function docstrings for all functions
|
|
50
|
+
- Complete type hints throughout codebase
|
|
51
|
+
- Detailed API documentation for NITRO client
|
|
52
|
+
|
|
53
|
+
#### Project Files
|
|
54
|
+
- `requirements.txt` - Dependency specification
|
|
55
|
+
- `.gitignore` - Comprehensive Python gitignore with security patterns
|
|
56
|
+
- `setup.py` - PyPI-ready installation script
|
|
57
|
+
- `LICENSE` - MIT License
|
|
58
|
+
- `TODO.md` - Structured improvement roadmap
|
|
59
|
+
|
|
60
|
+
#### README Improvements
|
|
61
|
+
- Badges (License, Python version)
|
|
62
|
+
- Features list with checkmarks
|
|
63
|
+
- Architecture diagram reference
|
|
64
|
+
- Prerequisites section
|
|
65
|
+
- Installation instructions (pip and package modes)
|
|
66
|
+
- Environment variables table
|
|
67
|
+
- Command-line arguments table
|
|
68
|
+
- Logging documentation with examples
|
|
69
|
+
- Step-by-step usage guide
|
|
70
|
+
- Example output for multiple scenarios
|
|
71
|
+
- Security considerations section
|
|
72
|
+
- Comprehensive troubleshooting guide
|
|
73
|
+
- Exit codes documentation
|
|
74
|
+
- Cron automation examples
|
|
75
|
+
|
|
76
|
+
### Changed
|
|
77
|
+
|
|
78
|
+
#### NITRO Client (`nitro.py`)
|
|
79
|
+
- Enhanced with comprehensive type hints
|
|
80
|
+
- Improved error messages with context (URLs, file paths)
|
|
81
|
+
- Better exception handling with specific types
|
|
82
|
+
- PEP 8 compliant formatting
|
|
83
|
+
- Complete docstrings for all 15 methods
|
|
84
|
+
|
|
85
|
+
#### Main Script (`netscaler-certbot-hook.py`)
|
|
86
|
+
- From ~271 lines to ~639 lines (with documentation)
|
|
87
|
+
- Eliminated ~80 lines of code duplication
|
|
88
|
+
- Better separation of concerns
|
|
89
|
+
- All functions are now independently testable
|
|
90
|
+
- Clear, descriptive function names
|
|
91
|
+
|
|
92
|
+
### Fixed
|
|
93
|
+
|
|
94
|
+
#### Critical Bug Fixes
|
|
95
|
+
- **SSL Verification Bug**: Fixed `verify_ssl` boolean conversion
|
|
96
|
+
- Before: `os.getenv('NS_VERIFY_SSL', True)` always returned True (string)
|
|
97
|
+
- After: `os.getenv('NS_VERIFY_SSL', 'true').lower() in ('true', '1', 'yes')`
|
|
98
|
+
- Proper file validation before operations
|
|
99
|
+
- Configuration validation at startup
|
|
100
|
+
- Better URL parsing
|
|
101
|
+
|
|
102
|
+
### Security
|
|
103
|
+
|
|
104
|
+
- SSL verification enabled by default
|
|
105
|
+
- Sensitive data excluded from `.gitignore` (certificates, keys, env files)
|
|
106
|
+
- Credentials not logged to output
|
|
107
|
+
- Certificate files validated before processing
|
|
108
|
+
- Chain certificates require manual approval for updates (prevents unexpected changes)
|
|
109
|
+
|
|
110
|
+
### Technical Details
|
|
111
|
+
|
|
112
|
+
#### Statistics
|
|
113
|
+
- **Total additions**: ~813 lines of improvements and documentation
|
|
114
|
+
- **Main script**: 271 → 639 lines (+368 lines documentation)
|
|
115
|
+
- **NITRO client**: 99 → 334 lines (+235 lines documentation)
|
|
116
|
+
- **README**: 87 → 417 lines (+330 lines documentation)
|
|
117
|
+
|
|
118
|
+
#### Backward Compatibility
|
|
119
|
+
- 100% backward compatible
|
|
120
|
+
- Same command-line interface
|
|
121
|
+
- Same environment variables
|
|
122
|
+
- Same behavior
|
|
123
|
+
- No breaking changes
|
|
124
|
+
|
|
125
|
+
#### Dependencies
|
|
126
|
+
- `pyOpenSSL>=20.0.0` - SSL certificate handling
|
|
127
|
+
- `requests>=2.25.0` - NITRO API communication
|
|
128
|
+
- Python 3.6+ required
|
|
129
|
+
|
|
130
|
+
### Migration Guide
|
|
131
|
+
|
|
132
|
+
No migration needed! The script works exactly as before. All changes are internal improvements.
|
|
133
|
+
|
|
134
|
+
Existing commands continue to work:
|
|
135
|
+
```bash
|
|
136
|
+
# Still works exactly as before
|
|
137
|
+
python3 netscaler-certbot-hook.py --name example.com
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
New optional flags available:
|
|
141
|
+
```bash
|
|
142
|
+
# New: Verbose mode
|
|
143
|
+
python3 netscaler-certbot-hook.py --name example.com --verbose
|
|
144
|
+
|
|
145
|
+
# New: Quiet mode
|
|
146
|
+
python3 netscaler-certbot-hook.py --name example.com --quiet
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## [0.0.1] - 2020-02-16
|
|
150
|
+
|
|
151
|
+
### Initial Release
|
|
152
|
+
|
|
153
|
+
- Basic certificate installation and renewal functionality
|
|
154
|
+
- NITRO API integration
|
|
155
|
+
- Let's Encrypt certificate support
|
|
156
|
+
- Chain certificate handling
|
|
157
|
+
- Configuration via environment variables
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
[1.0.0]: https://github.com/slauger/netscaler-certbot-hook/compare/v0.0.1...v1.0.0
|
|
162
|
+
[0.0.1]: https://github.com/slauger/netscaler-certbot-hook/releases/tag/v0.0.1
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Simon Lauger
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: netscaler-certbot-hook
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Automated SSL certificate management for Citrix NetScaler ADC using Certbot
|
|
5
|
+
Author-email: Simon Lauger <simon@lauger.de>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/slauger/netscaler-certbot-hook
|
|
8
|
+
Project-URL: Documentation, https://github.com/slauger/netscaler-certbot-hook#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/slauger/netscaler-certbot-hook
|
|
10
|
+
Project-URL: Issues, https://github.com/slauger/netscaler-certbot-hook/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/slauger/netscaler-certbot-hook/blob/master/CHANGELOG.md
|
|
12
|
+
Keywords: netscaler,citrix,adc,certbot,letsencrypt,ssl,certificate,automation
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.6
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Operating System :: OS Independent
|
|
24
|
+
Classifier: Topic :: System :: Systems Administration
|
|
25
|
+
Classifier: Topic :: Security :: Cryptography
|
|
26
|
+
Classifier: Topic :: Utilities
|
|
27
|
+
Requires-Python: >=3.6
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Requires-Dist: pyOpenSSL>=20.0.0
|
|
31
|
+
Requires-Dist: requests>=2.25.0
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# NetScaler Certbot Hook
|
|
35
|
+
|
|
36
|
+
[](https://opensource.org/licenses/MIT)
|
|
37
|
+
[](https://www.python.org/downloads/)
|
|
38
|
+
|
|
39
|
+
Automated SSL certificate management for Citrix NetScaler ADC. This tool seamlessly integrates with Certbot to install and renew Let's Encrypt certificates on NetScaler appliances via the NITRO API.
|
|
40
|
+
|
|
41
|
+
Perfect for automating certificate lifecycle management in combination with DNS-01 challenges for fully automated, hands-free certificate renewals.
|
|
42
|
+
|
|
43
|
+
## Features
|
|
44
|
+
|
|
45
|
+
- ✅ **Automated Certificate Installation** - Upload and install certificates with a single command
|
|
46
|
+
- ✅ **Smart Updates** - Only updates certificates when serial numbers differ
|
|
47
|
+
- ✅ **Chain Certificate Handling** - Automatic linking to intermediate certificates
|
|
48
|
+
- ✅ **Configuration Persistence** - Automatically saves NetScaler configuration
|
|
49
|
+
- ✅ **Idempotent Operations** - Safe to run repeatedly, only changes when needed
|
|
50
|
+
- ✅ **Custom Certificate Paths** - Supports non-standard certificate locations
|
|
51
|
+
- ✅ **Comprehensive Validation** - Pre-flight checks for files, credentials, and configuration
|
|
52
|
+
- ✅ **Detailed Error Messages** - Clear feedback when something goes wrong
|
|
53
|
+
- ✅ **Type-Safe** - Full type hints for IDE support and static analysis
|
|
54
|
+
|
|
55
|
+
## Architecture
|
|
56
|
+
|
|
57
|
+

|
|
58
|
+
|
|
59
|
+
The script connects to your NetScaler via NITRO API, compares certificate serial numbers, and performs uploads/installations only when necessary. Chain certificates are handled separately for security reasons.
|
|
60
|
+
|
|
61
|
+
## Prerequisites
|
|
62
|
+
|
|
63
|
+
- **Python** 3.6 or higher
|
|
64
|
+
- **Citrix NetScaler ADC** with NITRO API access
|
|
65
|
+
- **Certbot** (for Let's Encrypt certificate enrollment)
|
|
66
|
+
- **Network access** to NetScaler management interface
|
|
67
|
+
|
|
68
|
+
## Installation
|
|
69
|
+
|
|
70
|
+
### Option 1: From PyPI (Recommended)
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Install directly from PyPI
|
|
74
|
+
pip install netscaler-certbot-hook
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
After installation, the `netscaler-certbot-hook` command will be available system-wide.
|
|
78
|
+
|
|
79
|
+
### Option 2: From Source
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Clone the repository
|
|
83
|
+
git clone https://github.com/slauger/netscaler-certbot-hook.git
|
|
84
|
+
cd netscaler-certbot-hook
|
|
85
|
+
|
|
86
|
+
# Install in development mode
|
|
87
|
+
pip install -e .
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Option 3: Install dependencies only
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# For manual script execution
|
|
94
|
+
pip install -r requirements.txt
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Dependencies
|
|
98
|
+
|
|
99
|
+
- `pyOpenSSL>=20.0.0` - SSL certificate handling
|
|
100
|
+
- `requests>=2.25.0` - NITRO API communication
|
|
101
|
+
|
|
102
|
+
## Configuration
|
|
103
|
+
|
|
104
|
+
### Environment Variables
|
|
105
|
+
|
|
106
|
+
The script requires the following environment variables:
|
|
107
|
+
|
|
108
|
+
| Variable | Required | Default | Description |
|
|
109
|
+
|----------|----------|---------|-------------|
|
|
110
|
+
| `NS_URL` | Yes | - | NetScaler management URL (e.g., `https://192.168.10.10`) |
|
|
111
|
+
| `NS_LOGIN` | No | `nsroot` | NetScaler administrator username |
|
|
112
|
+
| `NS_PASSWORD` | No | `nsroot` | NetScaler administrator password |
|
|
113
|
+
| `NS_VERIFY_SSL` | No | `true` | Verify SSL certificate (`true`, `false`, `1`, `0`) |
|
|
114
|
+
|
|
115
|
+
**Example:**
|
|
116
|
+
```bash
|
|
117
|
+
export NS_URL=https://192.168.10.10
|
|
118
|
+
export NS_LOGIN=nsroot
|
|
119
|
+
export NS_PASSWORD=your-secure-password
|
|
120
|
+
export NS_VERIFY_SSL=true
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Command-Line Arguments
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
netscaler-certbot-hook --help
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Note:** If installed from PyPI, use `netscaler-certbot-hook`. If running from source, use `netscaler-certbot-hook` or `python3 -m netscaler_certbot_hook`.
|
|
130
|
+
|
|
131
|
+
| Argument | Required | Default | Description |
|
|
132
|
+
|----------|----------|---------|-------------|
|
|
133
|
+
| `--name` | Yes | - | Certificate object name on NetScaler |
|
|
134
|
+
| `--chain` | No | `letsencrypt` | Chain certificate object name |
|
|
135
|
+
| `--cert` | No | `/etc/letsencrypt/live/<name>/cert.pem` | Path to certificate file |
|
|
136
|
+
| `--privkey` | No | `/etc/letsencrypt/live/<name>/privkey.pem` | Path to private key file |
|
|
137
|
+
| `--chain-cert` | No | `/etc/letsencrypt/live/<name>/chain.pem` | Path to chain certificate file |
|
|
138
|
+
| `--verbose` | No | `false` | Enable verbose output (DEBUG level) |
|
|
139
|
+
| `--quiet` | No | `false` | Suppress all output except errors |
|
|
140
|
+
|
|
141
|
+
## Usage
|
|
142
|
+
|
|
143
|
+
### Step 1: Enroll Certificate with Certbot
|
|
144
|
+
|
|
145
|
+
First, obtain a certificate from Let's Encrypt using Certbot with DNS-01 challenge:
|
|
146
|
+
|
|
147
|
+
#### Example with Cloudflare DNS:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
certbot --text --agree-tos --non-interactive certonly \
|
|
151
|
+
--cert-name 'example.com' \
|
|
152
|
+
-d 'example.com' \
|
|
153
|
+
-d 'www.example.com' \
|
|
154
|
+
-a dns-cloudflare \
|
|
155
|
+
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
|
|
156
|
+
--keep-until-expiring
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
#### Example with other DNS providers:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# Route53 (AWS)
|
|
163
|
+
certbot certonly --dns-route53 -d example.com
|
|
164
|
+
|
|
165
|
+
# Google Cloud DNS
|
|
166
|
+
certbot certonly --dns-google -d example.com
|
|
167
|
+
|
|
168
|
+
# Manual DNS (for testing)
|
|
169
|
+
certbot certonly --manual --preferred-challenges dns -d example.com
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Step 2: Install Certificate on NetScaler
|
|
173
|
+
|
|
174
|
+
#### Basic Usage (Default Paths):
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
netscaler-certbot-hook --name example.com
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
#### Custom Certificate Paths:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
netscaler-certbot-hook --name example.com \
|
|
184
|
+
--cert /path/to/cert.pem \
|
|
185
|
+
--privkey /path/to/privkey.pem \
|
|
186
|
+
--chain-cert /path/to/chain.pem
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### Custom Chain Certificate Name:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
netscaler-certbot-hook --name example.com --chain my-chain
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
#### Verbose Output for Debugging:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
# Enable detailed DEBUG logging
|
|
199
|
+
netscaler-certbot-hook --name example.com --verbose
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### Quiet Mode for Cron Jobs:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
# Suppress all output except errors
|
|
206
|
+
netscaler-certbot-hook --name example.com --quiet
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Step 3: Automate with Cron
|
|
210
|
+
|
|
211
|
+
Add to your crontab for automatic renewal:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# Renew certificates daily and update NetScaler
|
|
215
|
+
0 3 * * * certbot renew --quiet && netscaler-certbot-hook --name example.com
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Or create a Certbot deploy hook:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
# /etc/letsencrypt/renewal-hooks/deploy/netscaler-hook.sh
|
|
222
|
+
#!/bin/bash
|
|
223
|
+
export NS_URL=https://192.168.10.10
|
|
224
|
+
export NS_LOGIN=nsroot
|
|
225
|
+
export NS_PASSWORD=your-password
|
|
226
|
+
|
|
227
|
+
netscaler-certbot-hook --name $RENEWED_DOMAINS
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Make it executable:
|
|
231
|
+
```bash
|
|
232
|
+
chmod +x /etc/letsencrypt/renewal-hooks/deploy/netscaler-hook.sh
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Logging
|
|
236
|
+
|
|
237
|
+
The script uses Python's built-in logging framework for structured output. You can control the verbosity with command-line flags:
|
|
238
|
+
|
|
239
|
+
### Log Levels
|
|
240
|
+
|
|
241
|
+
| Flag | Log Level | Use Case |
|
|
242
|
+
|------|-----------|----------|
|
|
243
|
+
| *default* | `INFO` | Standard output showing progress |
|
|
244
|
+
| `--verbose` | `DEBUG` | Detailed output for troubleshooting |
|
|
245
|
+
| `--quiet` | `ERROR` | Minimal output, only errors |
|
|
246
|
+
|
|
247
|
+
### Examples
|
|
248
|
+
|
|
249
|
+
**Standard Output (INFO level):**
|
|
250
|
+
```bash
|
|
251
|
+
netscaler-certbot-hook --name example.com
|
|
252
|
+
```
|
|
253
|
+
Shows all important operations and their status.
|
|
254
|
+
|
|
255
|
+
**Verbose Mode (DEBUG level):**
|
|
256
|
+
```bash
|
|
257
|
+
netscaler-certbot-hook --name example.com --verbose
|
|
258
|
+
```
|
|
259
|
+
Shows additional debugging information including:
|
|
260
|
+
- Connection details
|
|
261
|
+
- Configuration values
|
|
262
|
+
- Detailed operation steps
|
|
263
|
+
|
|
264
|
+
**Quiet Mode (ERROR level):**
|
|
265
|
+
```bash
|
|
266
|
+
netscaler-certbot-hook --name example.com --quiet
|
|
267
|
+
```
|
|
268
|
+
Only shows errors. Perfect for cron jobs where you only want to be notified of failures.
|
|
269
|
+
|
|
270
|
+
### Logging for Cron Jobs
|
|
271
|
+
|
|
272
|
+
For automated cron jobs, use `--quiet` to suppress normal output:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
# Only log errors to file
|
|
276
|
+
0 3 * * * netscaler-certbot-hook --name example.com --quiet 2>> /var/log/netscaler-cert-errors.log
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Or use standard output with log rotation:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
# Log all output with rotation
|
|
283
|
+
0 3 * * * netscaler-certbot-hook --name example.com >> /var/log/netscaler-cert.log 2>&1
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Example Output
|
|
287
|
+
|
|
288
|
+
### Initial Setup
|
|
289
|
+
|
|
290
|
+
When running for the first time:
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
chain certificate letsencrypt not found
|
|
294
|
+
uploading chain certificate as letsencrypt-1581896753.crt
|
|
295
|
+
installing chain certificate with serial 13298795840390663119752826058995181320
|
|
296
|
+
certificate example.com not found
|
|
297
|
+
uploading certificate as example.com-1581896753.crt
|
|
298
|
+
uploading private key as example.com-1581896753.key
|
|
299
|
+
installing certificate with serial 409596789458967997345847308430335698529007
|
|
300
|
+
link certificate example.com to chain certificate letsencrypt
|
|
301
|
+
saving configuration
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Certificate Update
|
|
305
|
+
|
|
306
|
+
When certificate has been renewed:
|
|
307
|
+
|
|
308
|
+
```
|
|
309
|
+
chain certificate letsencrypt found with serial 13298795840390663119752826058995181320
|
|
310
|
+
installed chain certificate matches our serial - nothing to do
|
|
311
|
+
certificate example.com found with serial 409596789458967997345847308430335698529007
|
|
312
|
+
uploading certificate as example.com-1581896812.crt
|
|
313
|
+
uploading private key as example.com-1581896812.key
|
|
314
|
+
update certificate example.com
|
|
315
|
+
link certificate example.com to chain certificate letsencrypt
|
|
316
|
+
certificate link was already present - nothing to do
|
|
317
|
+
saving configuration
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### No Changes Needed
|
|
321
|
+
|
|
322
|
+
When certificate is already up-to-date:
|
|
323
|
+
|
|
324
|
+
```
|
|
325
|
+
chain certificate letsencrypt found with serial 13298795840390663119752826058995181320
|
|
326
|
+
installed chain certificate matches our serial - nothing to do
|
|
327
|
+
certificate example.com found with serial 409596789458967997345847308430335698529007
|
|
328
|
+
installed certificate matches our serial - nothing to do
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## Security Considerations
|
|
332
|
+
|
|
333
|
+
### Chain Certificate Updates
|
|
334
|
+
|
|
335
|
+
For security reasons, the script does **not** automatically update chain certificates if the serial number differs. This prevents potential security issues from unexpected chain updates. Manual intervention is required if you need to update a chain certificate.
|
|
336
|
+
|
|
337
|
+
### Credential Management
|
|
338
|
+
|
|
339
|
+
**Never commit credentials to version control!** Use environment variables or secure credential management:
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
# Store in secure location
|
|
343
|
+
echo "export NS_PASSWORD='your-password'" > ~/.netscaler-credentials
|
|
344
|
+
chmod 600 ~/.netscaler-credentials
|
|
345
|
+
|
|
346
|
+
# Source when needed
|
|
347
|
+
source ~/.netscaler-credentials
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### SSL Verification
|
|
351
|
+
|
|
352
|
+
Always enable SSL verification in production:
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
export NS_VERIFY_SSL=true
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Only disable for testing or development environments.
|
|
359
|
+
|
|
360
|
+
## Troubleshooting
|
|
361
|
+
|
|
362
|
+
### Common Issues
|
|
363
|
+
|
|
364
|
+
#### "required environment variable NS_URL not set"
|
|
365
|
+
|
|
366
|
+
**Solution:** Set the required environment variable:
|
|
367
|
+
```bash
|
|
368
|
+
export NS_URL=https://your-netscaler-ip
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
#### "Certificate file not found"
|
|
372
|
+
|
|
373
|
+
**Solution:** Verify certificate path or let the script use default paths:
|
|
374
|
+
```bash
|
|
375
|
+
ls /etc/letsencrypt/live/example.com/
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
#### "Failed to connect to NetScaler"
|
|
379
|
+
|
|
380
|
+
**Possible causes:**
|
|
381
|
+
- NetScaler is not reachable (check network/firewall)
|
|
382
|
+
- Wrong IP address or URL
|
|
383
|
+
- SSL verification issues
|
|
384
|
+
|
|
385
|
+
**Solution:**
|
|
386
|
+
```bash
|
|
387
|
+
# Test connectivity
|
|
388
|
+
ping your-netscaler-ip
|
|
389
|
+
|
|
390
|
+
# Temporary disable SSL verification for testing
|
|
391
|
+
export NS_VERIFY_SSL=false
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
#### "HTTP error from NetScaler: 401"
|
|
395
|
+
|
|
396
|
+
**Solution:** Check credentials:
|
|
397
|
+
```bash
|
|
398
|
+
export NS_LOGIN=correct-username
|
|
399
|
+
export NS_PASSWORD=correct-password
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
#### "serial of installed chain certificate does not match"
|
|
403
|
+
|
|
404
|
+
**Solution:** Chain certificates cannot be auto-updated. Manually update or contact administrator.
|
|
405
|
+
|
|
406
|
+
### Debug Mode
|
|
407
|
+
|
|
408
|
+
For detailed output, check the Python script directly or examine NetScaler logs.
|
|
409
|
+
|
|
410
|
+
### Exit Codes
|
|
411
|
+
|
|
412
|
+
- `0` - Success (certificate installed, updated, or already current)
|
|
413
|
+
- `1` - Error (configuration, validation, or API error)
|
|
414
|
+
|
|
415
|
+
## API Reference
|
|
416
|
+
|
|
417
|
+
The script uses the Citrix NetScaler NITRO API. For more information:
|
|
418
|
+
- [NetScaler NITRO API Documentation](https://docs.citrix.com/en-us/citrix-adc/current-release/nitro-api.html)
|
|
419
|
+
|
|
420
|
+
## Development
|
|
421
|
+
|
|
422
|
+
### Running Tests
|
|
423
|
+
|
|
424
|
+
Currently, the project focuses on production use. Unit tests are planned for future releases.
|
|
425
|
+
|
|
426
|
+
### Contributing
|
|
427
|
+
|
|
428
|
+
Contributions are welcome! Please:
|
|
429
|
+
1. Fork the repository
|
|
430
|
+
2. Create a feature branch
|
|
431
|
+
3. Make your changes
|
|
432
|
+
4. Submit a pull request
|
|
433
|
+
|
|
434
|
+
### Code Quality
|
|
435
|
+
|
|
436
|
+
The codebase follows:
|
|
437
|
+
- PEP 8 style guidelines
|
|
438
|
+
- Type hints throughout
|
|
439
|
+
- Comprehensive docstrings
|
|
440
|
+
- Professional error handling
|
|
441
|
+
|
|
442
|
+
## License
|
|
443
|
+
|
|
444
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
445
|
+
|
|
446
|
+
## Authors
|
|
447
|
+
|
|
448
|
+
- **Simon Lauger** - [@slauger](https://github.com/slauger)
|
|
449
|
+
|
|
450
|
+
## Acknowledgments
|
|
451
|
+
|
|
452
|
+
- Citrix for the NetScaler NITRO API
|
|
453
|
+
- Let's Encrypt for free SSL certificates
|
|
454
|
+
- The Certbot team for excellent automation tools
|
|
455
|
+
|
|
456
|
+
## Support
|
|
457
|
+
|
|
458
|
+
For issues, questions, or contributions, please use the [GitHub issue tracker](https://github.com/slauger/netscaler-certbot-hook/issues).
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
**Made with ❤️ for automated certificate management**
|