mirror of
https://github.com/angristan/openvpn-install.git
synced 2025-12-14 16:17:03 +01:00
feat: add CLIENT_FILEPATH env var and fix client file ownership (#962)
Fix #961 - Adds CLIENT_FILEPATH env var to specify custom output path for .ovpn files - Automatically sets correct ownership (chown) and permissions (chmod go-rw) when client name matches a system user --------- Co-authored-by: Stanislas Lange <git@slange.me>
This commit is contained in:
10
README.md
10
README.md
@@ -101,6 +101,9 @@ If you want to customise your installation, you can export them or specify them
|
|||||||
- `CLIENT_CERT_DURATION_DAYS=3650`
|
- `CLIENT_CERT_DURATION_DAYS=3650`
|
||||||
- `SERVER_CERT_DURATION_DAYS=3650`
|
- `SERVER_CERT_DURATION_DAYS=3650`
|
||||||
- `NEW_CLIENT=y` (set to `n` to skip client creation after installation)
|
- `NEW_CLIENT=y` (set to `n` to skip client creation after installation)
|
||||||
|
- `CLIENT_FILEPATH=/custom/path/client.ovpn` (optional, overrides default output path)
|
||||||
|
|
||||||
|
The `.ovpn` file is saved to `CLIENT_FILEPATH` if defined, otherwise: the client's home directory if it exists (`/home/$CLIENT`), otherwise `SUDO_USER`'s home, otherwise `/root`. When the client name matches a system user, the script automatically sets proper ownership and permissions on the file.
|
||||||
|
|
||||||
If the server is behind NAT, you can specify its endpoint with the `ENDPOINT` variable. If the endpoint is the public IP address which it is behind, you can use `ENDPOINT=$(curl -4 ifconfig.co)` (the script will default to this). The endpoint can be an IPv4 or a domain.
|
If the server is behind NAT, you can specify its endpoint with the `ENDPOINT` variable. If the endpoint is the public IP address which it is behind, you can use `ENDPOINT=$(curl -4 ifconfig.co)` (the script will default to this). The endpoint can be an IPv4 or a domain.
|
||||||
|
|
||||||
@@ -119,18 +122,19 @@ The following Bash script adds a new user `foo` to an existing OpenVPN configura
|
|||||||
export MENU_OPTION="1"
|
export MENU_OPTION="1"
|
||||||
export CLIENT="foo"
|
export CLIENT="foo"
|
||||||
export PASS="1" # set to "2" for a password-protected client, and set PASSPHRASE
|
export PASS="1" # set to "2" for a password-protected client, and set PASSPHRASE
|
||||||
|
export CLIENT_FILEPATH="" # optional, custom path for .ovpn file
|
||||||
./openvpn-install.sh
|
./openvpn-install.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
### Headless User Revocation
|
### Headless User Revocation
|
||||||
|
|
||||||
It's also possible to automate the revocation of an existing user. The key is to provide the `MENU_OPTION` variable set to `2` along with either `CLIENT` (client name) or `CLIENTNUMBER` (1-based index from the client list).
|
It's also possible to automate the revocation of an existing user. The key is to provide the `MENU_OPTION` variable set to `3` along with either `CLIENT` (client name) or `CLIENTNUMBER` (1-based index from the client list).
|
||||||
|
|
||||||
The following Bash script revokes the existing user `foo`:
|
The following Bash script revokes the existing user `foo`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
export MENU_OPTION="2"
|
export MENU_OPTION="3"
|
||||||
export CLIENT="foo"
|
export CLIENT="foo"
|
||||||
./openvpn-install.sh
|
./openvpn-install.sh
|
||||||
```
|
```
|
||||||
@@ -139,7 +143,7 @@ Alternatively, you can use the client number:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
export MENU_OPTION="2"
|
export MENU_OPTION="3"
|
||||||
export CLIENTNUMBER="1" # Revokes the first client in the list
|
export CLIENTNUMBER="1" # Revokes the first client in the list
|
||||||
./openvpn-install.sh
|
./openvpn-install.sh
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1562,6 +1562,29 @@ function getHomeDir() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Helper function to get the owner of a client config file (if client matches a system user)
|
||||||
|
function getClientOwner() {
|
||||||
|
local client="$1"
|
||||||
|
if [ -e "/home/${client}" ]; then
|
||||||
|
echo "${client}"
|
||||||
|
elif [ "${SUDO_USER}" ] && [ "${SUDO_USER}" != "root" ]; then
|
||||||
|
echo "${SUDO_USER}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Helper function to set proper ownership and permissions on client config file
|
||||||
|
function setClientConfigPermissions() {
|
||||||
|
local filepath="$1"
|
||||||
|
local owner="$2"
|
||||||
|
|
||||||
|
if [[ -n "$owner" ]]; then
|
||||||
|
local owner_group
|
||||||
|
owner_group=$(id -gn "$owner")
|
||||||
|
chmod go-rw "$filepath"
|
||||||
|
chown "$owner:$owner_group" "$filepath"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Helper function to regenerate the CRL after certificate changes
|
# Helper function to regenerate the CRL after certificate changes
|
||||||
function regenerateCRL() {
|
function regenerateCRL() {
|
||||||
export EASYRSA_CRL_DAYS=$DEFAULT_CRL_VALIDITY_DURATION_DAYS
|
export EASYRSA_CRL_DAYS=$DEFAULT_CRL_VALIDITY_DURATION_DAYS
|
||||||
@@ -1572,9 +1595,10 @@ function regenerateCRL() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Helper function to generate .ovpn client config file
|
# Helper function to generate .ovpn client config file
|
||||||
|
# Usage: generateClientConfig <client_name> <filepath>
|
||||||
function generateClientConfig() {
|
function generateClientConfig() {
|
||||||
local client="$1"
|
local client="$1"
|
||||||
local home_dir="$2"
|
local filepath="$2"
|
||||||
|
|
||||||
# Determine if we use tls-crypt-v2, tls-crypt, or tls-auth
|
# Determine if we use tls-crypt-v2, tls-crypt, or tls-auth
|
||||||
local tls_sig=""
|
local tls_sig=""
|
||||||
@@ -1587,7 +1611,7 @@ function generateClientConfig() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Generate the custom client.ovpn
|
# Generate the custom client.ovpn
|
||||||
run_cmd "Creating client config" cp /etc/openvpn/server/client-template.txt "$home_dir/$client.ovpn"
|
run_cmd "Creating client config" cp /etc/openvpn/server/client-template.txt "$filepath"
|
||||||
{
|
{
|
||||||
echo "<ca>"
|
echo "<ca>"
|
||||||
cat "/etc/openvpn/server/easy-rsa/pki/ca.crt"
|
cat "/etc/openvpn/server/easy-rsa/pki/ca.crt"
|
||||||
@@ -1628,7 +1652,7 @@ function generateClientConfig() {
|
|||||||
echo "</tls-auth>"
|
echo "</tls-auth>"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
} >>"$home_dir/$client.ovpn"
|
} >>"$filepath"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Helper function to list valid clients and select one
|
# Helper function to list valid clients and select one
|
||||||
@@ -1821,12 +1845,26 @@ function newClient() {
|
|||||||
log_success "Client $CLIENT added and is valid for $CLIENT_CERT_DURATION_DAYS days."
|
log_success "Client $CLIENT added and is valid for $CLIENT_CERT_DURATION_DAYS days."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Determine output file path
|
||||||
|
local clientFilePath
|
||||||
|
if [[ -n "$CLIENT_FILEPATH" ]]; then
|
||||||
|
clientFilePath="$CLIENT_FILEPATH"
|
||||||
|
else
|
||||||
|
local homeDir
|
||||||
|
homeDir=$(getHomeDir "$CLIENT")
|
||||||
|
clientFilePath="$homeDir/$CLIENT.ovpn"
|
||||||
|
fi
|
||||||
|
|
||||||
# Generate the .ovpn config file
|
# Generate the .ovpn config file
|
||||||
homeDir=$(getHomeDir "$CLIENT")
|
generateClientConfig "$CLIENT" "$clientFilePath"
|
||||||
generateClientConfig "$CLIENT" "$homeDir"
|
|
||||||
|
# Set proper ownership and permissions if client matches a system user
|
||||||
|
local clientOwner
|
||||||
|
clientOwner=$(getClientOwner "$CLIENT")
|
||||||
|
setClientConfigPermissions "$clientFilePath" "$clientOwner"
|
||||||
|
|
||||||
log_menu ""
|
log_menu ""
|
||||||
log_success "The configuration file has been written to $homeDir/$CLIENT.ovpn."
|
log_success "The configuration file has been written to $clientFilePath."
|
||||||
log_info "Download the .ovpn file and import it in your OpenVPN client."
|
log_info "Download the .ovpn file and import it in your OpenVPN client."
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
@@ -1850,7 +1888,7 @@ function revokeClient() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renewClient() {
|
function renewClient() {
|
||||||
local homeDir client_cert_duration_days
|
local client_cert_duration_days
|
||||||
|
|
||||||
log_header "Renew Client Certificate"
|
log_header "Renew Client Certificate"
|
||||||
log_prompt "Select the existing client certificate you want to renew"
|
log_prompt "Select the existing client certificate you want to renew"
|
||||||
@@ -1883,13 +1921,27 @@ function renewClient() {
|
|||||||
# Regenerate the CRL
|
# Regenerate the CRL
|
||||||
regenerateCRL
|
regenerateCRL
|
||||||
|
|
||||||
|
# Determine output file path
|
||||||
|
local clientFilePath
|
||||||
|
if [[ -n "$CLIENT_FILEPATH" ]]; then
|
||||||
|
clientFilePath="$CLIENT_FILEPATH"
|
||||||
|
else
|
||||||
|
local homeDir
|
||||||
|
homeDir=$(getHomeDir "$CLIENT")
|
||||||
|
clientFilePath="$homeDir/$CLIENT.ovpn"
|
||||||
|
fi
|
||||||
|
|
||||||
# Regenerate the .ovpn file with the new certificate
|
# Regenerate the .ovpn file with the new certificate
|
||||||
homeDir=$(getHomeDir "$CLIENT")
|
generateClientConfig "$CLIENT" "$clientFilePath"
|
||||||
generateClientConfig "$CLIENT" "$homeDir"
|
|
||||||
|
# Set proper ownership and permissions if client matches a system user
|
||||||
|
local clientOwner
|
||||||
|
clientOwner=$(getClientOwner "$CLIENT")
|
||||||
|
setClientConfigPermissions "$clientFilePath" "$clientOwner"
|
||||||
|
|
||||||
log_menu ""
|
log_menu ""
|
||||||
log_success "Certificate for client $CLIENT renewed and is valid for $client_cert_duration_days days."
|
log_success "Certificate for client $CLIENT renewed and is valid for $client_cert_duration_days days."
|
||||||
log_info "The new configuration file has been written to $homeDir/$CLIENT.ovpn."
|
log_info "The new configuration file has been written to $clientFilePath."
|
||||||
log_info "Download the new .ovpn file and import it in your OpenVPN client."
|
log_info "Download the new .ovpn file and import it in your OpenVPN client."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user