-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial script creation and Readme update
- Loading branch information
Showing
2 changed files
with
312 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,260 @@ | ||
#!/usr/bin/env bash | ||
|
||
function usage() { | ||
|
||
echo -e "\nThe script can be used to split or merge ovpn file." | ||
echo -e "\nBasic Usage:\n $0 [options..] <ovpn-config-file> \n" | ||
echo -e "Open VPN config file can be passed either as argument or through option (--source | -s ). \n" | ||
echo -e "\nOptions:" | ||
echo -e "-p | --split - flag to split ovpn file." | ||
echo -e "-s<filepath> | --source <filepath> - Option to pass the source ovpn file." | ||
echo -e "-d<folderpath> | --destination <folderpath> - Destination location where the newly created config to be stored. " | ||
echo -e "-m | --merge [optional parameter : auto] - simple flag to merge file. takes a optional parameter [auto]." | ||
echo -e "if auto is set, then the script tries to identify certificates and keys from path specified in ovpn file. This can be overridden by other options." | ||
echo -e "--ca <filepath> - option to specify the location of the CA file. " | ||
echo -e "--cert <filepath> - option to specify the location of the certificate file." | ||
echo -e "--key <filepath> - option to specify the location of the key file. " | ||
echo -e "--tls-auth <filepath> - option to specify the location of the tls-auth file." | ||
echo -e "--dh-params <filepath> - opton to specify the location of the dh params file." | ||
echo -e "-h | --help - Display usage instructions.\n" | ||
echo -e "Example usage for merge:\n" | ||
echo -e "$0 -m=auto -s home/openvpn/vpn.ovpn" | ||
echo -e "--ca home/openvpn/vpn-ca.crt" | ||
echo -e "-d home/openvpn/merged/ --cert home/openvpn/vpn-client.crt --key home/openvpn/vpn-client.key" | ||
echo -e "\n\nExample usage for split:\n" | ||
echo -e "$0 -s home/openvpn/vpn.ovpn -d home/openvpn/split/\n" | ||
exit 0 | ||
} | ||
|
||
shortHelp() { | ||
echo -e "\nNo valid arguments provided, use -h/--help flag to see usage." | ||
exit 0 | ||
} | ||
|
||
# Print short help | ||
[ "$#" = "0" ] && shortHelp | ||
|
||
PROGNAME=${0##*/} | ||
SHORTOPTS="hm::ps:d:D:" | ||
LONGOPTS="help,merge::,split,source:,destination:,ca:,cert:,key:,tls-auth:,dh-params:" | ||
set -o errexit -o noclobber -o pipefail | ||
|
||
OPTS=$(getopt -s bash --options $SHORTOPTS --longoptions $LONGOPTS --name $PROGNAME -- "$@") | ||
eval set -- "$OPTS" | ||
|
||
#Base variable declaration | ||
FILE="" | ||
DESTINATION="" | ||
MERGE=false | ||
MERGEAUTO=false | ||
SPLIT=false | ||
CA="" | ||
CERT="" | ||
KEY="" | ||
TLS_AUTH="" | ||
DH="" | ||
|
||
while true; do | ||
case "$1" in | ||
-m | --merge) | ||
case "$2" in | ||
"") | ||
MERGE=true | ||
shift 2 | ||
;; | ||
"auto" | "=auto") | ||
MERGE=true | ||
MERGEAUTO=true | ||
shift 2 | ||
;; | ||
esac | ||
;; | ||
-p | --split) | ||
SPLIT=true | ||
shift | ||
;; | ||
-s | --source) | ||
FILE="$2" | ||
shift 2 | ||
;; | ||
-d | --destination) | ||
DESTINATION="$2" | ||
shift 2 | ||
;; | ||
-h | --help) | ||
usage | ||
shift | ||
;; | ||
--ca) | ||
CA="$2" | ||
shift 2 | ||
;; | ||
--cert) | ||
CERT="$2" | ||
shift 2 | ||
;; | ||
--key) | ||
KEY="$2" | ||
shift 2 | ||
;; | ||
--tls-auth) | ||
TLS_AUTH="$2" | ||
shift 2 | ||
;; | ||
--dh-params) | ||
DH="$2" | ||
shift 2 | ||
;; | ||
--) | ||
shift | ||
break | ||
;; | ||
*) break ;; | ||
esac | ||
done | ||
|
||
# if both merge and split flags are set then throw error | ||
if [ "$MERGE" = true ] && [ "$SPLIT" = true ]; then | ||
echo "Cannot set flag merge and split at the same time." | ||
exit 1 | ||
fi | ||
|
||
# if no flags are set then throw error | ||
if [ "$MERGE" = false ] && [ "$SPLIT" = false ]; then | ||
echo "Atlest one of the merge or split flag must be set." | ||
exit 1 | ||
fi | ||
|
||
# If argument is passed to the script, the source set through options is overridden by argument value. | ||
# argument takes priority. | ||
if [ ! -z "$1" ]; then | ||
FILE="$1" | ||
fi | ||
|
||
# Check if the file parameter is not empty | ||
if [ -z "$FILE" ]; then | ||
echo "Filepath of openvpn config is mandatory." | ||
exit 1 | ||
fi | ||
|
||
# If Destination folder is specified then we check whether the folder is there, if not the folder is created. | ||
if [ ! -z "$DESTINATION" ] && [ ! -d "$DESTINATION" ]; then | ||
mkdir -p $DESTINATION | ||
if [ $? -ne 0 ]; then | ||
echo "Creating destination directory failed." | ||
exit 1 | ||
fi | ||
DESTINATION="$(readlink -f $DESTINATION)" | ||
|
||
fi | ||
|
||
if [ ! -z "$DESTINATION" ] && [ -d "$DESTINATION" ]; then | ||
|
||
DESTINATION="$(readlink -f $DESTINATION)" | ||
fi | ||
|
||
# If Destination is empty then create files in the same directory as of source file | ||
if [ -z "$DESTINATION" ]; then | ||
|
||
DESTINATION="$(dirname "$(readlink -f $FILE)")" | ||
fi | ||
|
||
if [ ! -f "$FILE" ]; then | ||
echo "Invalid file name : $FILE" | ||
exit 1 | ||
fi | ||
|
||
FULLFILENAME=$(basename $FILE) | ||
FILENAME="${FULLFILENAME%.*}" | ||
EXTENSION="${FULLFILENAME##*.}" | ||
|
||
if [ ! -z "$SPLIT" ] && [ "$SPLIT" = true ]; then | ||
|
||
if [ $(echo $EXTENSION | tr [:upper:] [:lower:]) = $(echo "conf" | tr [:upper:] [:lower:]) ] || [ $(echo $EXTENSION | tr [:upper:] [:lower:]) = $(echo "ovpn" | tr [:upper:] [:lower:]) ]; then | ||
|
||
NEWPATH=${DESTINATION}/${FILENAME}- | ||
NEWFILE=${NEWPATH}updated.ovpn | ||
cp $FILE $NEWFILE | ||
|
||
if grep -q "<ca>" "$FILE"; then | ||
sed '1,/<ca>/d;/<\/ca>/,$d' $FILE > ${NEWPATH}ca.crt | ||
sed -i "/<ca>/,/<\/ca>/c\ca ${NEWPATH}ca.crt" ${NEWFILE} | ||
fi | ||
if grep -q "<cert>" "$FILE"; then | ||
sed '1,/<cert>/d;/<\/cert>/,$d' $FILE > ${NEWPATH}client.crt | ||
sed -i "/<cert>/,/<\/cert>/c\cert ${NEWPATH}client.crt" ${NEWFILE} | ||
fi | ||
if grep -q "<key>" "$FILE"; then | ||
sed '1,/<key>/d;/<\/key>/,$d' $FILE > ${NEWPATH}client.key | ||
sed -i "/<key>/,/<\/key>/c\key ${NEWPATH}client.key" ${NEWFILE} | ||
fi | ||
if grep -q "<tls-auth>" "$FILE"; then | ||
sed '1,/<tls-auth>/d;/<\/tls-auth>/,$d' $FILE > ${NEWPATH}ta.key | ||
sed -i "/<tls-auth>/,/<\/tls-auth>/c\tls-auth ${NEWPATH}ta.key" ${NEWFILE} | ||
fi | ||
if grep -q "<dh>" "$FILE"; then | ||
sed '1,/<dh>/d;/<\/dh>/,$d' $FILE > ${NEWPATH}dh.pem | ||
sed -i "/<dh>/,/<\/dh>/c\dh ${NEWPATH}dh.pem" ${NEWFILE} | ||
fi | ||
|
||
else | ||
echo "Invalid open vpn file extension" | ||
exit 1 | ||
fi | ||
|
||
fi | ||
|
||
if [ ! -z "$MERGE" ] && [ "$MERGE" = true ]; then | ||
NEWFILE=${DESTINATION}/${FILENAME}-merged.ovpn | ||
cp $FILE $NEWFILE | ||
|
||
# if merge auto is set then try to find the certificate/key path from the source ovpn file | ||
if [ "$MERGEAUTO" = true ]; then | ||
for tagname in ca cert key tls_auth dh; do | ||
VAR=$(echo "$tagname" | tr '[:lower:]' '[:upper:]') | ||
VARVAL="${!VAR}" | ||
if [ -z "$VARVAL" ]; then | ||
tagname=$(echo "$tagname" | sed "s/_/-/") | ||
path="$(sed -n -e "s/^$tagname //p" $NEWFILE | xargs readlink -f)" | ||
if [ ! -z "$path" ]; then | ||
declare $VAR=$path | ||
fi | ||
fi | ||
done | ||
fi | ||
|
||
if [ -z "$CA" ] && [ -z "$CERT" ] && [ -z "$KEY" ] && [ -z "$TLSAUTH" ]; then | ||
echo "Atleast one option (ca,cert,key,tls-auth) parameter is required." | ||
exit 1 | ||
fi | ||
|
||
for tagname in ca cert key tls_auth dh; do | ||
#convert the tagname to upper to access the variables. | ||
VAR=$(echo "$tagname" | tr '[:lower:]' '[:upper:]') | ||
VARVAL="${!VAR}" | ||
if [ ! -z "$VARVAL" ] && [ ! -f "$VARVAL" ]; then | ||
echo "Provided ${tagname} file does not exist." | ||
exit 1 | ||
fi | ||
#replace underscore with hypen in tagname for searching the file | ||
tagname=$(echo "$tagname" | sed "s/_/-/") | ||
if [ ! -z "$VARVAL" ]; then | ||
#If substitution exist in the config file then replace it with inline content | ||
#else append the config file with the content of the file | ||
if grep -qE "^${tagname}[ \t]*.*$" "$NEWFILE"; then | ||
FULLFILENAME=$(basename $VARVAL) | ||
sed -i "/${tagname} .*${FULLFILENAME}/c\<${tagname}>\n<\/${tagname}>" ${NEWFILE} | ||
sed -i "/<${tagname}>/r ${VARVAL}" ${NEWFILE} | ||
else | ||
echo "<${tagname}>" >> ${NEWFILE} | ||
cat ${VARVAL} >> ${NEWFILE} | ||
echo "</${tagname}>" >> ${NEWFILE} | ||
fi | ||
fi | ||
|
||
done | ||
#preserve file timestamp from original file so if the original config is updated | ||
#then we know that the generated one config needs to be regenerated. | ||
filemodtime=$(stat -c%y "$FILE" | sed 's/[ ]\+/ /g') | ||
touch -m -d "$filemodtime" "$NEWFILE" | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,53 @@ | ||
# OVPN-Config-Manipulator | ||
# OVPN Config Manipulator | ||
Open VPN config file (.ovpn) contains several certificates and key files which are required for the setup. This script allows you to merge those certificates and keys into single config file. The script can also be used to split a single self-contained ovpn config file to individual config and cert files. | ||
|
||
## Dependencies | ||
|
||
This script does not have very many dependencies. Most of the dependencies are available by default in most linux platforms. This script requires the following packages. | ||
|
||
- sed (Stream editor) | ||
- grep | ||
- awk | ||
- getopt | ||
- xargs | ||
|
||
## Usage | ||
The script can be used to merge or split OVPN file. | ||
|
||
Basic Usage: | ||
|
||
./OVPN-config-manipulator.sh [options..] <ovpn-config-file> | ||
|
||
To split a OVPN file into main config file and relevant cert and key files, the script can be used as follows | ||
|
||
./OVPN-config-manipulator.sh -p -s home/openvpn/vpn.ovpn -d home/openvpn/split/ | ||
|
||
In the above example `-p` option specifies split operation. The source file is read from location specified in `-s` option. The final split files are stored in the directory specified in `-d` option. | ||
|
||
To merge OVPN config file and relevant certificates, the script can be used as follows | ||
|
||
./OVPN-config-manipulator.sh -m=auto -s home/openvpn/vpn.ovpn -d home/openvpn/merged/ \ | ||
--ca home/openvpn/vpn-ca.crt \ | ||
--cert home/openvpn/vpn-client.crt \ | ||
--key home/openvpn/vpn-client.key | ||
|
||
In the above example `-m` option indicates merge operation. The source file is loaded from file specified in `-s` option and output single merged config file is saved to destination folder specified in `-d` option. The `auto` option set to `-m` flag will make the script to auto detect ca file, certificate, key, tls-auth certificate and dh-params files from path specified within the OVPN file. If those values exists within the OVPN config file then the script automatically tries to read content from the location and link it to the file. The values can be overriden by options provided to the script. So in the above example Certificate authority file will be loaded from location provided by `--ca` option even if the path is different in the OVPN config file. | ||
|
||
List of options available in the script are | ||
|
||
-p | --split - flag to split ovpn file. | ||
-s<filepath> | --source <filepath> - Option to pass the source ovpn file. | ||
-d<folderpath> | --destination <folderpath> - Destination location where the newly created config to be stored. | ||
-m | --merge [optional parameter : auto] - flag to merge file. takes a optional parameter [auto]. | ||
if auto is set, then the script tries to identify certificates and keys from path specified in ovpn file. This can be overridden by other options. | ||
--ca <filepath> - option to specify the location of the CA file. | ||
--cert <filepath> - option to specify the location of the certificate file. | ||
--key <filepath> - option to specify the location of the key file. | ||
--tls-auth <filepath> - option to specify the location of the tls-auth file. | ||
--dh-params <filepath> - opton to specify the location of the dh params file. | ||
-h | --help - Display usage instructions. | ||
|
||
## License | ||
|
||
MIT | ||
|