openvpn-install.sh 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344
  1. #!/bin/bash
  2. # shellcheck disable=SC1091,SC2164,SC2034,SC1072,SC1073,SC1009
  3. # Secure OpenVPN server installer for Debian, Ubuntu, CentOS, Amazon Linux 2, Fedora, Oracle Linux 8, Arch Linux, Rocky Linux and AlmaLinux.
  4. # https://github.com/angristan/openvpn-install
  5. function isRoot() {
  6. if [ "$EUID" -ne 0 ]; then
  7. return 1
  8. fi
  9. }
  10. function tunAvailable() {
  11. if [ ! -e /dev/net/tun ]; then
  12. return 1
  13. fi
  14. }
  15. function checkOS() {
  16. if [[ -e /etc/debian_version ]]; then
  17. OS="debian"
  18. source /etc/os-release
  19. if [[ $ID == "debian" || $ID == "raspbian" ]]; then
  20. if [[ $VERSION_ID -lt 9 ]]; then
  21. echo "⚠️ Your version of Debian is not supported."
  22. echo ""
  23. echo "However, if you're using Debian >= 9 or unstable/testing then you can continue, at your own risk."
  24. echo ""
  25. until [[ $CONTINUE =~ (y|n) ]]; do
  26. read -rp "Continue? [y/n]: " -e CONTINUE
  27. done
  28. if [[ $CONTINUE == "n" ]]; then
  29. exit 1
  30. fi
  31. fi
  32. elif [[ $ID == "ubuntu" ]]; then
  33. OS="ubuntu"
  34. MAJOR_UBUNTU_VERSION=$(echo "$VERSION_ID" | cut -d '.' -f1)
  35. if [[ $MAJOR_UBUNTU_VERSION -lt 16 ]]; then
  36. echo "⚠️ Your version of Ubuntu is not supported."
  37. echo ""
  38. echo "However, if you're using Ubuntu >= 16.04 or beta, then you can continue, at your own risk."
  39. echo ""
  40. until [[ $CONTINUE =~ (y|n) ]]; do
  41. read -rp "Continue? [y/n]: " -e CONTINUE
  42. done
  43. if [[ $CONTINUE == "n" ]]; then
  44. exit 1
  45. fi
  46. fi
  47. fi
  48. elif [[ -e /etc/system-release ]]; then
  49. source /etc/os-release
  50. if [[ $ID == "fedora" || $ID_LIKE == "fedora" ]]; then
  51. OS="fedora"
  52. fi
  53. if [[ $ID == "centos" || $ID == "rocky" || $ID == "almalinux" ]]; then
  54. OS="centos"
  55. if [[ ${VERSION_ID%.*} -lt 7 ]]; then
  56. echo "⚠️ Your version of CentOS is not supported."
  57. echo ""
  58. echo "The script only support CentOS 7 and CentOS 8."
  59. echo ""
  60. exit 1
  61. fi
  62. fi
  63. if [[ $ID == "ol" ]]; then
  64. OS="oracle"
  65. if [[ ! $VERSION_ID =~ (8) ]]; then
  66. echo "Your version of Oracle Linux is not supported."
  67. echo ""
  68. echo "The script only support Oracle Linux 8."
  69. exit 1
  70. fi
  71. fi
  72. if [[ $ID == "amzn" ]]; then
  73. OS="amzn"
  74. if [[ $VERSION_ID != "2" ]]; then
  75. echo "⚠️ Your version of Amazon Linux is not supported."
  76. echo ""
  77. echo "The script only support Amazon Linux 2."
  78. echo ""
  79. exit 1
  80. fi
  81. fi
  82. elif [[ -e /etc/arch-release ]]; then
  83. OS=arch
  84. else
  85. echo "Looks like you aren't running this installer on a Debian, Ubuntu, Fedora, CentOS, Amazon Linux 2, Oracle Linux 8 or Arch Linux system"
  86. exit 1
  87. fi
  88. }
  89. function initialCheck() {
  90. if ! isRoot; then
  91. echo "Sorry, you need to run this as root"
  92. exit 1
  93. fi
  94. if ! tunAvailable; then
  95. echo "TUN is not available"
  96. exit 1
  97. fi
  98. checkOS
  99. }
  100. function installUnbound() {
  101. # If Unbound isn't installed, install it
  102. if [[ ! -e /etc/unbound/unbound.conf ]]; then
  103. if [[ $OS =~ (debian|ubuntu) ]]; then
  104. apt-get install -y unbound
  105. # Configuration
  106. echo 'interface: 10.8.0.1
  107. access-control: 10.8.0.1/24 allow
  108. hide-identity: yes
  109. hide-version: yes
  110. use-caps-for-id: yes
  111. prefetch: yes' >>/etc/unbound/unbound.conf
  112. elif [[ $OS =~ (centos|amzn|oracle) ]]; then
  113. yum install -y unbound
  114. # Configuration
  115. sed -i 's|# interface: 0.0.0.0$|interface: 10.8.0.1|' /etc/unbound/unbound.conf
  116. sed -i 's|# access-control: 127.0.0.0/8 allow|access-control: 10.8.0.1/24 allow|' /etc/unbound/unbound.conf
  117. sed -i 's|# hide-identity: no|hide-identity: yes|' /etc/unbound/unbound.conf
  118. sed -i 's|# hide-version: no|hide-version: yes|' /etc/unbound/unbound.conf
  119. sed -i 's|use-caps-for-id: no|use-caps-for-id: yes|' /etc/unbound/unbound.conf
  120. elif [[ $OS == "fedora" ]]; then
  121. dnf install -y unbound
  122. # Configuration
  123. sed -i 's|# interface: 0.0.0.0$|interface: 10.8.0.1|' /etc/unbound/unbound.conf
  124. sed -i 's|# access-control: 127.0.0.0/8 allow|access-control: 10.8.0.1/24 allow|' /etc/unbound/unbound.conf
  125. sed -i 's|# hide-identity: no|hide-identity: yes|' /etc/unbound/unbound.conf
  126. sed -i 's|# hide-version: no|hide-version: yes|' /etc/unbound/unbound.conf
  127. sed -i 's|# use-caps-for-id: no|use-caps-for-id: yes|' /etc/unbound/unbound.conf
  128. elif [[ $OS == "arch" ]]; then
  129. pacman -Syu --noconfirm unbound
  130. # Get root servers list
  131. curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache
  132. if [[ ! -f /etc/unbound/unbound.conf.old ]]; then
  133. mv /etc/unbound/unbound.conf /etc/unbound/unbound.conf.old
  134. fi
  135. echo 'server:
  136. use-syslog: yes
  137. do-daemonize: no
  138. username: "unbound"
  139. directory: "/etc/unbound"
  140. trust-anchor-file: trusted-key.key
  141. root-hints: root.hints
  142. interface: 10.8.0.1
  143. access-control: 10.8.0.1/24 allow
  144. port: 53
  145. num-threads: 2
  146. use-caps-for-id: yes
  147. harden-glue: yes
  148. hide-identity: yes
  149. hide-version: yes
  150. qname-minimisation: yes
  151. prefetch: yes' >/etc/unbound/unbound.conf
  152. fi
  153. # IPv6 DNS for all OS
  154. if [[ $IPV6_SUPPORT == 'y' ]]; then
  155. echo 'interface: fd42:42:42:42::1
  156. access-control: fd42:42:42:42::/112 allow' >>/etc/unbound/unbound.conf
  157. fi
  158. if [[ ! $OS =~ (fedora|centos|amzn|oracle) ]]; then
  159. # DNS Rebinding fix
  160. echo "private-address: 10.0.0.0/8
  161. private-address: fd42:42:42:42::/112
  162. private-address: 172.16.0.0/12
  163. private-address: 192.168.0.0/16
  164. private-address: 169.254.0.0/16
  165. private-address: fd00::/8
  166. private-address: fe80::/10
  167. private-address: 127.0.0.0/8
  168. private-address: ::ffff:0:0/96" >>/etc/unbound/unbound.conf
  169. fi
  170. else # Unbound is already installed
  171. echo 'include: /etc/unbound/openvpn.conf' >>/etc/unbound/unbound.conf
  172. # Add Unbound 'server' for the OpenVPN subnet
  173. echo 'server:
  174. interface: 10.8.0.1
  175. access-control: 10.8.0.1/24 allow
  176. hide-identity: yes
  177. hide-version: yes
  178. use-caps-for-id: yes
  179. prefetch: yes
  180. private-address: 10.0.0.0/8
  181. private-address: fd42:42:42:42::/112
  182. private-address: 172.16.0.0/12
  183. private-address: 192.168.0.0/16
  184. private-address: 169.254.0.0/16
  185. private-address: fd00::/8
  186. private-address: fe80::/10
  187. private-address: 127.0.0.0/8
  188. private-address: ::ffff:0:0/96' >/etc/unbound/openvpn.conf
  189. if [[ $IPV6_SUPPORT == 'y' ]]; then
  190. echo 'interface: fd42:42:42:42::1
  191. access-control: fd42:42:42:42::/112 allow' >>/etc/unbound/openvpn.conf
  192. fi
  193. fi
  194. systemctl enable unbound
  195. systemctl restart unbound
  196. }
  197. function installQuestions() {
  198. echo "Welcome to the OpenVPN installer!"
  199. echo "The git repository is available at: https://github.com/angristan/openvpn-install"
  200. echo ""
  201. echo "I need to ask you a few questions before starting the setup."
  202. echo "You can leave the default options and just press enter if you are ok with them."
  203. echo ""
  204. echo "I need to know the IPv4 address of the network interface you want OpenVPN listening to."
  205. echo "Unless your server is behind NAT, it should be your public IPv4 address."
  206. # Detect public IPv4 address and pre-fill for the user
  207. IP=$(ip -4 addr | sed -ne 's|^.* inet \([^/]*\)/.* scope global.*$|\1|p' | head -1)
  208. if [[ -z $IP ]]; then
  209. # Detect public IPv6 address
  210. IP=$(ip -6 addr | sed -ne 's|^.* inet6 \([^/]*\)/.* scope global.*$|\1|p' | head -1)
  211. fi
  212. APPROVE_IP=${APPROVE_IP:-n}
  213. if [[ $APPROVE_IP =~ n ]]; then
  214. read -rp "IP address: " -e -i "$IP" IP
  215. fi
  216. # If $IP is a private IP address, the server must be behind NAT
  217. if echo "$IP" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192\.168)'; then
  218. echo ""
  219. echo "It seems this server is behind NAT. What is its public IPv4 address or hostname?"
  220. echo "We need it for the clients to connect to the server."
  221. PUBLICIP=$(curl -s https://api.ipify.org)
  222. until [[ $ENDPOINT != "" ]]; do
  223. read -rp "Public IPv4 address or hostname: " -e -i "$PUBLICIP" ENDPOINT
  224. done
  225. fi
  226. echo ""
  227. echo "Checking for IPv6 connectivity..."
  228. echo ""
  229. # "ping6" and "ping -6" availability varies depending on the distribution
  230. if type ping6 >/dev/null 2>&1; then
  231. PING6="ping6 -c3 ipv6.google.com > /dev/null 2>&1"
  232. else
  233. PING6="ping -6 -c3 ipv6.google.com > /dev/null 2>&1"
  234. fi
  235. if eval "$PING6"; then
  236. echo "Your host appears to have IPv6 connectivity."
  237. SUGGESTION="y"
  238. else
  239. echo "Your host does not appear to have IPv6 connectivity."
  240. SUGGESTION="n"
  241. fi
  242. echo ""
  243. # Ask the user if they want to enable IPv6 regardless its availability.
  244. until [[ $IPV6_SUPPORT =~ (y|n) ]]; do
  245. read -rp "Do you want to enable IPv6 support (NAT)? [y/n]: " -e -i $SUGGESTION IPV6_SUPPORT
  246. done
  247. echo ""
  248. echo "What port do you want OpenVPN to listen to?"
  249. echo " 1) Default: 1194"
  250. echo " 2) Custom"
  251. echo " 3) Random [49152-65535]"
  252. until [[ $PORT_CHOICE =~ ^[1-3]$ ]]; do
  253. read -rp "Port choice [1-3]: " -e -i 1 PORT_CHOICE
  254. done
  255. case $PORT_CHOICE in
  256. 1)
  257. PORT="1194"
  258. ;;
  259. 2)
  260. until [[ $PORT =~ ^[0-9]+$ ]] && [ "$PORT" -ge 1 ] && [ "$PORT" -le 65535 ]; do
  261. read -rp "Custom port [1-65535]: " -e -i 1194 PORT
  262. done
  263. ;;
  264. 3)
  265. # Generate random number within private ports range
  266. PORT=$(shuf -i49152-65535 -n1)
  267. echo "Random Port: $PORT"
  268. ;;
  269. esac
  270. echo ""
  271. echo "What protocol do you want OpenVPN to use?"
  272. echo "UDP is faster. Unless it is not available, you shouldn't use TCP."
  273. echo " 1) UDP"
  274. echo " 2) TCP"
  275. until [[ $PROTOCOL_CHOICE =~ ^[1-2]$ ]]; do
  276. read -rp "Protocol [1-2]: " -e -i 1 PROTOCOL_CHOICE
  277. done
  278. case $PROTOCOL_CHOICE in
  279. 1)
  280. PROTOCOL="udp"
  281. ;;
  282. 2)
  283. PROTOCOL="tcp"
  284. ;;
  285. esac
  286. echo ""
  287. echo "What DNS resolvers do you want to use with the VPN?"
  288. echo " 1) Current system resolvers (from /etc/resolv.conf)"
  289. echo " 2) Self-hosted DNS Resolver (Unbound)"
  290. echo " 3) Cloudflare (Anycast: worldwide)"
  291. echo " 4) Quad9 (Anycast: worldwide)"
  292. echo " 5) Quad9 uncensored (Anycast: worldwide)"
  293. echo " 6) FDN (France)"
  294. echo " 7) DNS.WATCH (Germany)"
  295. echo " 8) OpenDNS (Anycast: worldwide)"
  296. echo " 9) Google (Anycast: worldwide)"
  297. echo " 10) Yandex Basic (Russia)"
  298. echo " 11) AdGuard DNS (Anycast: worldwide)"
  299. echo " 12) NextDNS (Anycast: worldwide)"
  300. echo " 13) Custom"
  301. until [[ $DNS =~ ^[0-9]+$ ]] && [ "$DNS" -ge 1 ] && [ "$DNS" -le 13 ]; do
  302. read -rp "DNS [1-12]: " -e -i 11 DNS
  303. if [[ $DNS == 2 ]] && [[ -e /etc/unbound/unbound.conf ]]; then
  304. echo ""
  305. echo "Unbound is already installed."
  306. echo "You can allow the script to configure it in order to use it from your OpenVPN clients"
  307. echo "We will simply add a second server to /etc/unbound/unbound.conf for the OpenVPN subnet."
  308. echo "No changes are made to the current configuration."
  309. echo ""
  310. until [[ $CONTINUE =~ (y|n) ]]; do
  311. read -rp "Apply configuration changes to Unbound? [y/n]: " -e CONTINUE
  312. done
  313. if [[ $CONTINUE == "n" ]]; then
  314. # Break the loop and cleanup
  315. unset DNS
  316. unset CONTINUE
  317. fi
  318. elif [[ $DNS == "13" ]]; then
  319. until [[ $DNS1 =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ ]]; do
  320. read -rp "Primary DNS: " -e DNS1
  321. done
  322. until [[ $DNS2 =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ ]]; do
  323. read -rp "Secondary DNS (optional): " -e DNS2
  324. if [[ $DNS2 == "" ]]; then
  325. break
  326. fi
  327. done
  328. fi
  329. done
  330. echo ""
  331. echo "Do you want to use compression? It is not recommended since the VORACLE attack makes use of it."
  332. until [[ $COMPRESSION_ENABLED =~ (y|n) ]]; do
  333. read -rp"Enable compression? [y/n]: " -e -i n COMPRESSION_ENABLED
  334. done
  335. if [[ $COMPRESSION_ENABLED == "y" ]]; then
  336. echo "Choose which compression algorithm you want to use: (they are ordered by efficiency)"
  337. echo " 1) LZ4-v2"
  338. echo " 2) LZ4"
  339. echo " 3) LZ0"
  340. until [[ $COMPRESSION_CHOICE =~ ^[1-3]$ ]]; do
  341. read -rp"Compression algorithm [1-3]: " -e -i 1 COMPRESSION_CHOICE
  342. done
  343. case $COMPRESSION_CHOICE in
  344. 1)
  345. COMPRESSION_ALG="lz4-v2"
  346. ;;
  347. 2)
  348. COMPRESSION_ALG="lz4"
  349. ;;
  350. 3)
  351. COMPRESSION_ALG="lzo"
  352. ;;
  353. esac
  354. fi
  355. echo ""
  356. echo "Do you want to customize encryption settings?"
  357. echo "Unless you know what you're doing, you should stick with the default parameters provided by the script."
  358. echo "Note that whatever you choose, all the choices presented in the script are safe. (Unlike OpenVPN's defaults)"
  359. echo "See https://github.com/angristan/openvpn-install#security-and-encryption to learn more."
  360. echo ""
  361. until [[ $CUSTOMIZE_ENC =~ (y|n) ]]; do
  362. read -rp "Customize encryption settings? [y/n]: " -e -i n CUSTOMIZE_ENC
  363. done
  364. if [[ $CUSTOMIZE_ENC == "n" ]]; then
  365. # Use default, sane and fast parameters
  366. CIPHER="AES-128-GCM"
  367. CERT_TYPE="1" # ECDSA
  368. CERT_CURVE="prime256v1"
  369. CC_CIPHER="TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256"
  370. DH_TYPE="1" # ECDH
  371. DH_CURVE="prime256v1"
  372. HMAC_ALG="SHA256"
  373. TLS_SIG="1" # tls-crypt
  374. else
  375. echo ""
  376. echo "Choose which cipher you want to use for the data channel:"
  377. echo " 1) AES-128-GCM (recommended)"
  378. echo " 2) AES-192-GCM"
  379. echo " 3) AES-256-GCM"
  380. echo " 4) AES-128-CBC"
  381. echo " 5) AES-192-CBC"
  382. echo " 6) AES-256-CBC"
  383. until [[ $CIPHER_CHOICE =~ ^[1-6]$ ]]; do
  384. read -rp "Cipher [1-6]: " -e -i 1 CIPHER_CHOICE
  385. done
  386. case $CIPHER_CHOICE in
  387. 1)
  388. CIPHER="AES-128-GCM"
  389. ;;
  390. 2)
  391. CIPHER="AES-192-GCM"
  392. ;;
  393. 3)
  394. CIPHER="AES-256-GCM"
  395. ;;
  396. 4)
  397. CIPHER="AES-128-CBC"
  398. ;;
  399. 5)
  400. CIPHER="AES-192-CBC"
  401. ;;
  402. 6)
  403. CIPHER="AES-256-CBC"
  404. ;;
  405. esac
  406. echo ""
  407. echo "Choose what kind of certificate you want to use:"
  408. echo " 1) ECDSA (recommended)"
  409. echo " 2) RSA"
  410. until [[ $CERT_TYPE =~ ^[1-2]$ ]]; do
  411. read -rp"Certificate key type [1-2]: " -e -i 1 CERT_TYPE
  412. done
  413. case $CERT_TYPE in
  414. 1)
  415. echo ""
  416. echo "Choose which curve you want to use for the certificate's key:"
  417. echo " 1) prime256v1 (recommended)"
  418. echo " 2) secp384r1"
  419. echo " 3) secp521r1"
  420. until [[ $CERT_CURVE_CHOICE =~ ^[1-3]$ ]]; do
  421. read -rp"Curve [1-3]: " -e -i 1 CERT_CURVE_CHOICE
  422. done
  423. case $CERT_CURVE_CHOICE in
  424. 1)
  425. CERT_CURVE="prime256v1"
  426. ;;
  427. 2)
  428. CERT_CURVE="secp384r1"
  429. ;;
  430. 3)
  431. CERT_CURVE="secp521r1"
  432. ;;
  433. esac
  434. ;;
  435. 2)
  436. echo ""
  437. echo "Choose which size you want to use for the certificate's RSA key:"
  438. echo " 1) 2048 bits (recommended)"
  439. echo " 2) 3072 bits"
  440. echo " 3) 4096 bits"
  441. until [[ $RSA_KEY_SIZE_CHOICE =~ ^[1-3]$ ]]; do
  442. read -rp "RSA key size [1-3]: " -e -i 1 RSA_KEY_SIZE_CHOICE
  443. done
  444. case $RSA_KEY_SIZE_CHOICE in
  445. 1)
  446. RSA_KEY_SIZE="2048"
  447. ;;
  448. 2)
  449. RSA_KEY_SIZE="3072"
  450. ;;
  451. 3)
  452. RSA_KEY_SIZE="4096"
  453. ;;
  454. esac
  455. ;;
  456. esac
  457. echo ""
  458. echo "Choose which cipher you want to use for the control channel:"
  459. case $CERT_TYPE in
  460. 1)
  461. echo " 1) ECDHE-ECDSA-AES-128-GCM-SHA256 (recommended)"
  462. echo " 2) ECDHE-ECDSA-AES-256-GCM-SHA384"
  463. until [[ $CC_CIPHER_CHOICE =~ ^[1-2]$ ]]; do
  464. read -rp"Control channel cipher [1-2]: " -e -i 1 CC_CIPHER_CHOICE
  465. done
  466. case $CC_CIPHER_CHOICE in
  467. 1)
  468. CC_CIPHER="TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256"
  469. ;;
  470. 2)
  471. CC_CIPHER="TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384"
  472. ;;
  473. esac
  474. ;;
  475. 2)
  476. echo " 1) ECDHE-RSA-AES-128-GCM-SHA256 (recommended)"
  477. echo " 2) ECDHE-RSA-AES-256-GCM-SHA384"
  478. until [[ $CC_CIPHER_CHOICE =~ ^[1-2]$ ]]; do
  479. read -rp"Control channel cipher [1-2]: " -e -i 1 CC_CIPHER_CHOICE
  480. done
  481. case $CC_CIPHER_CHOICE in
  482. 1)
  483. CC_CIPHER="TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256"
  484. ;;
  485. 2)
  486. CC_CIPHER="TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384"
  487. ;;
  488. esac
  489. ;;
  490. esac
  491. echo ""
  492. echo "Choose what kind of Diffie-Hellman key you want to use:"
  493. echo " 1) ECDH (recommended)"
  494. echo " 2) DH"
  495. until [[ $DH_TYPE =~ [1-2] ]]; do
  496. read -rp"DH key type [1-2]: " -e -i 1 DH_TYPE
  497. done
  498. case $DH_TYPE in
  499. 1)
  500. echo ""
  501. echo "Choose which curve you want to use for the ECDH key:"
  502. echo " 1) prime256v1 (recommended)"
  503. echo " 2) secp384r1"
  504. echo " 3) secp521r1"
  505. while [[ $DH_CURVE_CHOICE != "1" && $DH_CURVE_CHOICE != "2" && $DH_CURVE_CHOICE != "3" ]]; do
  506. read -rp"Curve [1-3]: " -e -i 1 DH_CURVE_CHOICE
  507. done
  508. case $DH_CURVE_CHOICE in
  509. 1)
  510. DH_CURVE="prime256v1"
  511. ;;
  512. 2)
  513. DH_CURVE="secp384r1"
  514. ;;
  515. 3)
  516. DH_CURVE="secp521r1"
  517. ;;
  518. esac
  519. ;;
  520. 2)
  521. echo ""
  522. echo "Choose what size of Diffie-Hellman key you want to use:"
  523. echo " 1) 2048 bits (recommended)"
  524. echo " 2) 3072 bits"
  525. echo " 3) 4096 bits"
  526. until [[ $DH_KEY_SIZE_CHOICE =~ ^[1-3]$ ]]; do
  527. read -rp "DH key size [1-3]: " -e -i 1 DH_KEY_SIZE_CHOICE
  528. done
  529. case $DH_KEY_SIZE_CHOICE in
  530. 1)
  531. DH_KEY_SIZE="2048"
  532. ;;
  533. 2)
  534. DH_KEY_SIZE="3072"
  535. ;;
  536. 3)
  537. DH_KEY_SIZE="4096"
  538. ;;
  539. esac
  540. ;;
  541. esac
  542. echo ""
  543. # The "auth" options behaves differently with AEAD ciphers
  544. if [[ $CIPHER =~ CBC$ ]]; then
  545. echo "The digest algorithm authenticates data channel packets and tls-auth packets from the control channel."
  546. elif [[ $CIPHER =~ GCM$ ]]; then
  547. echo "The digest algorithm authenticates tls-auth packets from the control channel."
  548. fi
  549. echo "Which digest algorithm do you want to use for HMAC?"
  550. echo " 1) SHA-256 (recommended)"
  551. echo " 2) SHA-384"
  552. echo " 3) SHA-512"
  553. until [[ $HMAC_ALG_CHOICE =~ ^[1-3]$ ]]; do
  554. read -rp "Digest algorithm [1-3]: " -e -i 1 HMAC_ALG_CHOICE
  555. done
  556. case $HMAC_ALG_CHOICE in
  557. 1)
  558. HMAC_ALG="SHA256"
  559. ;;
  560. 2)
  561. HMAC_ALG="SHA384"
  562. ;;
  563. 3)
  564. HMAC_ALG="SHA512"
  565. ;;
  566. esac
  567. echo ""
  568. echo "You can add an additional layer of security to the control channel with tls-auth and tls-crypt"
  569. echo "tls-auth authenticates the packets, while tls-crypt authenticate and encrypt them."
  570. echo " 1) tls-crypt (recommended)"
  571. echo " 2) tls-auth"
  572. until [[ $TLS_SIG =~ [1-2] ]]; do
  573. read -rp "Control channel additional security mechanism [1-2]: " -e -i 1 TLS_SIG
  574. done
  575. fi
  576. echo ""
  577. echo "Okay, that was all I needed. We are ready to setup your OpenVPN server now."
  578. echo "You will be able to generate a client at the end of the installation."
  579. APPROVE_INSTALL=${APPROVE_INSTALL:-n}
  580. if [[ $APPROVE_INSTALL =~ n ]]; then
  581. read -n1 -r -p "Press any key to continue..."
  582. fi
  583. }
  584. function installOpenVPN() {
  585. if [[ $AUTO_INSTALL == "y" ]]; then
  586. # Set default choices so that no questions will be asked.
  587. APPROVE_INSTALL=${APPROVE_INSTALL:-y}
  588. APPROVE_IP=${APPROVE_IP:-y}
  589. IPV6_SUPPORT=${IPV6_SUPPORT:-n}
  590. PORT_CHOICE=${PORT_CHOICE:-1}
  591. PROTOCOL_CHOICE=${PROTOCOL_CHOICE:-1}
  592. DNS=${DNS:-1}
  593. COMPRESSION_ENABLED=${COMPRESSION_ENABLED:-n}
  594. CUSTOMIZE_ENC=${CUSTOMIZE_ENC:-n}
  595. CLIENT=${CLIENT:-client}
  596. PASS=${PASS:-1}
  597. CONTINUE=${CONTINUE:-y}
  598. # Behind NAT, we'll default to the publicly reachable IPv4/IPv6.
  599. if [[ $IPV6_SUPPORT == "y" ]]; then
  600. if ! PUBLIC_IP=$(curl -f --retry 5 --retry-connrefused https://ip.seeip.org); then
  601. PUBLIC_IP=$(dig -6 TXT +short o-o.myaddr.l.google.com @ns1.google.com | tr -d '"')
  602. fi
  603. else
  604. if ! PUBLIC_IP=$(curl -f --retry 5 --retry-connrefused -4 https://ip.seeip.org); then
  605. PUBLIC_IP=$(dig -4 TXT +short o-o.myaddr.l.google.com @ns1.google.com | tr -d '"')
  606. fi
  607. fi
  608. ENDPOINT=${ENDPOINT:-$PUBLIC_IP}
  609. fi
  610. # Run setup questions first, and set other variables if auto-install
  611. installQuestions
  612. # Get the "public" interface from the default route
  613. NIC=$(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)' | head -1)
  614. if [[ -z $NIC ]] && [[ $IPV6_SUPPORT == 'y' ]]; then
  615. NIC=$(ip -6 route show default | sed -ne 's/^default .* dev \([^ ]*\) .*$/\1/p')
  616. fi
  617. # $NIC can not be empty for script rm-openvpn-rules.sh
  618. if [[ -z $NIC ]]; then
  619. echo
  620. echo "Can not detect public interface."
  621. echo "This needs for setup MASQUERADE."
  622. until [[ $CONTINUE =~ (y|n) ]]; do
  623. read -rp "Continue? [y/n]: " -e CONTINUE
  624. done
  625. if [[ $CONTINUE == "n" ]]; then
  626. exit 1
  627. fi
  628. fi
  629. # If OpenVPN isn't installed yet, install it. This script is more-or-less
  630. # idempotent on multiple runs, but will only install OpenVPN from upstream
  631. # the first time.
  632. if [[ ! -e /etc/openvpn/server.conf ]]; then
  633. if [[ $OS =~ (debian|ubuntu) ]]; then
  634. apt-get update
  635. apt-get -y install ca-certificates gnupg
  636. # We add the OpenVPN repo to get the latest version.
  637. if [[ $VERSION_ID == "16.04" ]]; then
  638. echo "deb http://build.openvpn.net/debian/openvpn/stable xenial main" >/etc/apt/sources.list.d/openvpn.list
  639. wget -O - https://swupdate.openvpn.net/repos/repo-public.gpg | apt-key add -
  640. apt-get update
  641. fi
  642. # Ubuntu > 16.04 and Debian > 8 have OpenVPN >= 2.4 without the need of a third party repository.
  643. apt-get install -y openvpn iptables openssl wget ca-certificates curl
  644. elif [[ $OS == 'centos' ]]; then
  645. yum install -y epel-release
  646. yum install -y openvpn iptables openssl wget ca-certificates curl tar 'policycoreutils-python*'
  647. elif [[ $OS == 'oracle' ]]; then
  648. yum install -y oracle-epel-release-el8
  649. yum-config-manager --enable ol8_developer_EPEL
  650. yum install -y openvpn iptables openssl wget ca-certificates curl tar policycoreutils-python-utils
  651. elif [[ $OS == 'amzn' ]]; then
  652. amazon-linux-extras install -y epel
  653. yum install -y openvpn iptables openssl wget ca-certificates curl
  654. elif [[ $OS == 'fedora' ]]; then
  655. dnf install -y openvpn iptables openssl wget ca-certificates curl policycoreutils-python-utils
  656. elif [[ $OS == 'arch' ]]; then
  657. # Install required dependencies and upgrade the system
  658. pacman --needed --noconfirm -Syu openvpn iptables openssl wget ca-certificates curl
  659. fi
  660. # An old version of easy-rsa was available by default in some openvpn packages
  661. if [[ -d /etc/openvpn/easy-rsa/ ]]; then
  662. rm -rf /etc/openvpn/easy-rsa/
  663. fi
  664. fi
  665. # Find out if the machine uses nogroup or nobody for the permissionless group
  666. if grep -qs "^nogroup:" /etc/group; then
  667. NOGROUP=nogroup
  668. else
  669. NOGROUP=nobody
  670. fi
  671. # Install the latest version of easy-rsa from source, if not already installed.
  672. if [[ ! -d /etc/openvpn/easy-rsa/ ]]; then
  673. local version="3.1.2"
  674. wget -O ~/easy-rsa.tgz https://github.com/OpenVPN/easy-rsa/releases/download/v${version}/EasyRSA-${version}.tgz
  675. mkdir -p /etc/openvpn/easy-rsa
  676. tar xzf ~/easy-rsa.tgz --strip-components=1 --no-same-owner --directory /etc/openvpn/easy-rsa
  677. rm -f ~/easy-rsa.tgz
  678. cd /etc/openvpn/easy-rsa/ || return
  679. case $CERT_TYPE in
  680. 1)
  681. echo "set_var EASYRSA_ALGO ec" >vars
  682. echo "set_var EASYRSA_CURVE $CERT_CURVE" >>vars
  683. ;;
  684. 2)
  685. echo "set_var EASYRSA_KEY_SIZE $RSA_KEY_SIZE" >vars
  686. ;;
  687. esac
  688. # Generate a random, alphanumeric identifier of 16 characters for CN and one for server name
  689. SERVER_CN="cn_$(head /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)"
  690. echo "$SERVER_CN" >SERVER_CN_GENERATED
  691. SERVER_NAME="server_$(head /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)"
  692. echo "$SERVER_NAME" >SERVER_NAME_GENERATED
  693. # Create the PKI, set up the CA, the DH params and the server certificate
  694. ./easyrsa init-pki
  695. EASYRSA_CA_EXPIRE=3650 ./easyrsa --batch --req-cn="$SERVER_CN" build-ca nopass
  696. if [[ $DH_TYPE == "2" ]]; then
  697. # ECDH keys are generated on-the-fly so we don't need to generate them beforehand
  698. openssl dhparam -out dh.pem $DH_KEY_SIZE
  699. fi
  700. EASYRSA_CERT_EXPIRE=3650 ./easyrsa --batch build-server-full "$SERVER_NAME" nopass
  701. EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
  702. case $TLS_SIG in
  703. 1)
  704. # Generate tls-crypt key
  705. openvpn --genkey --secret /etc/openvpn/tls-crypt.key
  706. ;;
  707. 2)
  708. # Generate tls-auth key
  709. openvpn --genkey --secret /etc/openvpn/tls-auth.key
  710. ;;
  711. esac
  712. else
  713. # If easy-rsa is already installed, grab the generated SERVER_NAME
  714. # for client configs
  715. cd /etc/openvpn/easy-rsa/ || return
  716. SERVER_NAME=$(cat SERVER_NAME_GENERATED)
  717. fi
  718. # Move all the generated files
  719. cp pki/ca.crt pki/private/ca.key "pki/issued/$SERVER_NAME.crt" "pki/private/$SERVER_NAME.key" /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn
  720. if [[ $DH_TYPE == "2" ]]; then
  721. cp dh.pem /etc/openvpn
  722. fi
  723. # Make cert revocation list readable for non-root
  724. chmod 644 /etc/openvpn/crl.pem
  725. # Generate server.conf
  726. echo "port $PORT" >/etc/openvpn/server.conf
  727. if [[ $IPV6_SUPPORT == 'n' ]]; then
  728. echo "proto $PROTOCOL" >>/etc/openvpn/server.conf
  729. elif [[ $IPV6_SUPPORT == 'y' ]]; then
  730. echo "proto ${PROTOCOL}6" >>/etc/openvpn/server.conf
  731. fi
  732. echo "dev tun
  733. user nobody
  734. group $NOGROUP
  735. persist-key
  736. persist-tun
  737. keepalive 10 120
  738. topology subnet
  739. server 10.8.0.0 255.255.255.0
  740. ifconfig-pool-persist ipp.txt" >>/etc/openvpn/server.conf
  741. # DNS resolvers
  742. case $DNS in
  743. 1) # Current system resolvers
  744. # Locate the proper resolv.conf
  745. # Needed for systems running systemd-resolved
  746. if grep -q "127.0.0.53" "/etc/resolv.conf"; then
  747. RESOLVCONF='/run/systemd/resolve/resolv.conf'
  748. else
  749. RESOLVCONF='/etc/resolv.conf'
  750. fi
  751. # Obtain the resolvers from resolv.conf and use them for OpenVPN
  752. sed -ne 's/^nameserver[[:space:]]\+\([^[:space:]]\+\).*$/\1/p' $RESOLVCONF | while read -r line; do
  753. # Copy, if it's a IPv4 |or| if IPv6 is enabled, IPv4/IPv6 does not matter
  754. if [[ $line =~ ^[0-9.]*$ ]] || [[ $IPV6_SUPPORT == 'y' ]]; then
  755. echo "push \"dhcp-option DNS $line\"" >>/etc/openvpn/server.conf
  756. fi
  757. done
  758. ;;
  759. 2) # Self-hosted DNS resolver (Unbound)
  760. echo 'push "dhcp-option DNS 10.8.0.1"' >>/etc/openvpn/server.conf
  761. if [[ $IPV6_SUPPORT == 'y' ]]; then
  762. echo 'push "dhcp-option DNS fd42:42:42:42::1"' >>/etc/openvpn/server.conf
  763. fi
  764. ;;
  765. 3) # Cloudflare
  766. echo 'push "dhcp-option DNS 1.0.0.1"' >>/etc/openvpn/server.conf
  767. echo 'push "dhcp-option DNS 1.1.1.1"' >>/etc/openvpn/server.conf
  768. ;;
  769. 4) # Quad9
  770. echo 'push "dhcp-option DNS 9.9.9.9"' >>/etc/openvpn/server.conf
  771. echo 'push "dhcp-option DNS 149.112.112.112"' >>/etc/openvpn/server.conf
  772. ;;
  773. 5) # Quad9 uncensored
  774. echo 'push "dhcp-option DNS 9.9.9.10"' >>/etc/openvpn/server.conf
  775. echo 'push "dhcp-option DNS 149.112.112.10"' >>/etc/openvpn/server.conf
  776. ;;
  777. 6) # FDN
  778. echo 'push "dhcp-option DNS 80.67.169.40"' >>/etc/openvpn/server.conf
  779. echo 'push "dhcp-option DNS 80.67.169.12"' >>/etc/openvpn/server.conf
  780. ;;
  781. 7) # DNS.WATCH
  782. echo 'push "dhcp-option DNS 84.200.69.80"' >>/etc/openvpn/server.conf
  783. echo 'push "dhcp-option DNS 84.200.70.40"' >>/etc/openvpn/server.conf
  784. ;;
  785. 8) # OpenDNS
  786. echo 'push "dhcp-option DNS 208.67.222.222"' >>/etc/openvpn/server.conf
  787. echo 'push "dhcp-option DNS 208.67.220.220"' >>/etc/openvpn/server.conf
  788. ;;
  789. 9) # Google
  790. echo 'push "dhcp-option DNS 8.8.8.8"' >>/etc/openvpn/server.conf
  791. echo 'push "dhcp-option DNS 8.8.4.4"' >>/etc/openvpn/server.conf
  792. ;;
  793. 10) # Yandex Basic
  794. echo 'push "dhcp-option DNS 77.88.8.8"' >>/etc/openvpn/server.conf
  795. echo 'push "dhcp-option DNS 77.88.8.1"' >>/etc/openvpn/server.conf
  796. ;;
  797. 11) # AdGuard DNS
  798. echo 'push "dhcp-option DNS 94.140.14.14"' >>/etc/openvpn/server.conf
  799. echo 'push "dhcp-option DNS 94.140.15.15"' >>/etc/openvpn/server.conf
  800. ;;
  801. 12) # NextDNS
  802. echo 'push "dhcp-option DNS 45.90.28.167"' >>/etc/openvpn/server.conf
  803. echo 'push "dhcp-option DNS 45.90.30.167"' >>/etc/openvpn/server.conf
  804. ;;
  805. 13) # Custom DNS
  806. echo "push \"dhcp-option DNS $DNS1\"" >>/etc/openvpn/server.conf
  807. if [[ $DNS2 != "" ]]; then
  808. echo "push \"dhcp-option DNS $DNS2\"" >>/etc/openvpn/server.conf
  809. fi
  810. ;;
  811. esac
  812. echo 'push "redirect-gateway def1 bypass-dhcp"' >>/etc/openvpn/server.conf
  813. # IPv6 network settings if needed
  814. if [[ $IPV6_SUPPORT == 'y' ]]; then
  815. echo 'server-ipv6 fd42:42:42:42::/112
  816. tun-ipv6
  817. push tun-ipv6
  818. push "route-ipv6 2000::/3"
  819. push "redirect-gateway ipv6"' >>/etc/openvpn/server.conf
  820. fi
  821. if [[ $COMPRESSION_ENABLED == "y" ]]; then
  822. echo "compress $COMPRESSION_ALG" >>/etc/openvpn/server.conf
  823. fi
  824. if [[ $DH_TYPE == "1" ]]; then
  825. echo "dh none" >>/etc/openvpn/server.conf
  826. echo "ecdh-curve $DH_CURVE" >>/etc/openvpn/server.conf
  827. elif [[ $DH_TYPE == "2" ]]; then
  828. echo "dh dh.pem" >>/etc/openvpn/server.conf
  829. fi
  830. case $TLS_SIG in
  831. 1)
  832. echo "tls-crypt tls-crypt.key" >>/etc/openvpn/server.conf
  833. ;;
  834. 2)
  835. echo "tls-auth tls-auth.key 0" >>/etc/openvpn/server.conf
  836. ;;
  837. esac
  838. echo "crl-verify crl.pem
  839. ca ca.crt
  840. cert $SERVER_NAME.crt
  841. key $SERVER_NAME.key
  842. auth $HMAC_ALG
  843. cipher $CIPHER
  844. ncp-ciphers $CIPHER
  845. tls-server
  846. tls-version-min 1.2
  847. tls-cipher $CC_CIPHER
  848. client-config-dir /etc/openvpn/ccd
  849. status /var/log/openvpn/status.log
  850. verb 3" >>/etc/openvpn/server.conf
  851. # Create client-config-dir dir
  852. mkdir -p /etc/openvpn/ccd
  853. # Create log dir
  854. mkdir -p /var/log/openvpn
  855. # Enable routing
  856. echo 'net.ipv4.ip_forward=1' >/etc/sysctl.d/99-openvpn.conf
  857. if [[ $IPV6_SUPPORT == 'y' ]]; then
  858. echo 'net.ipv6.conf.all.forwarding=1' >>/etc/sysctl.d/99-openvpn.conf
  859. fi
  860. # Apply sysctl rules
  861. sysctl --system
  862. # If SELinux is enabled and a custom port was selected, we need this
  863. if hash sestatus 2>/dev/null; then
  864. if sestatus | grep "Current mode" | grep -qs "enforcing"; then
  865. if [[ $PORT != '1194' ]]; then
  866. semanage port -a -t openvpn_port_t -p "$PROTOCOL" "$PORT"
  867. fi
  868. fi
  869. fi
  870. # Finally, restart and enable OpenVPN
  871. if [[ $OS == 'arch' || $OS == 'fedora' || $OS == 'centos' || $OS == 'oracle' ]]; then
  872. # Don't modify package-provided service
  873. cp /usr/lib/systemd/system/openvpn-server@.service /etc/systemd/system/openvpn-server@.service
  874. # Workaround to fix OpenVPN service on OpenVZ
  875. sed -i 's|LimitNPROC|#LimitNPROC|' /etc/systemd/system/openvpn-server@.service
  876. # Another workaround to keep using /etc/openvpn/
  877. sed -i 's|/etc/openvpn/server|/etc/openvpn|' /etc/systemd/system/openvpn-server@.service
  878. systemctl daemon-reload
  879. systemctl enable openvpn-server@server
  880. systemctl restart openvpn-server@server
  881. elif [[ $OS == "ubuntu" ]] && [[ $VERSION_ID == "16.04" ]]; then
  882. # On Ubuntu 16.04, we use the package from the OpenVPN repo
  883. # This package uses a sysvinit service
  884. systemctl enable openvpn
  885. systemctl start openvpn
  886. else
  887. # Don't modify package-provided service
  888. cp /lib/systemd/system/openvpn\@.service /etc/systemd/system/openvpn\@.service
  889. # Workaround to fix OpenVPN service on OpenVZ
  890. sed -i 's|LimitNPROC|#LimitNPROC|' /etc/systemd/system/openvpn\@.service
  891. # Another workaround to keep using /etc/openvpn/
  892. sed -i 's|/etc/openvpn/server|/etc/openvpn|' /etc/systemd/system/openvpn\@.service
  893. systemctl daemon-reload
  894. systemctl enable openvpn@server
  895. systemctl restart openvpn@server
  896. fi
  897. if [[ $DNS == 2 ]]; then
  898. installUnbound
  899. fi
  900. # Add iptables rules in two scripts
  901. mkdir -p /etc/iptables
  902. # Script to add rules
  903. echo "#!/bin/sh
  904. iptables -t nat -I POSTROUTING 1 -s 10.8.0.0/24 -o $NIC -j MASQUERADE
  905. iptables -I INPUT 1 -i tun0 -j ACCEPT
  906. iptables -I FORWARD 1 -i $NIC -o tun0 -j ACCEPT
  907. iptables -I FORWARD 1 -i tun0 -o $NIC -j ACCEPT
  908. iptables -I INPUT 1 -i $NIC -p $PROTOCOL --dport $PORT -j ACCEPT" >/etc/iptables/add-openvpn-rules.sh
  909. if [[ $IPV6_SUPPORT == 'y' ]]; then
  910. echo "ip6tables -t nat -I POSTROUTING 1 -s fd42:42:42:42::/112 -o $NIC -j MASQUERADE
  911. ip6tables -I INPUT 1 -i tun0 -j ACCEPT
  912. ip6tables -I FORWARD 1 -i $NIC -o tun0 -j ACCEPT
  913. ip6tables -I FORWARD 1 -i tun0 -o $NIC -j ACCEPT
  914. ip6tables -I INPUT 1 -i $NIC -p $PROTOCOL --dport $PORT -j ACCEPT" >>/etc/iptables/add-openvpn-rules.sh
  915. fi
  916. # Script to remove rules
  917. echo "#!/bin/sh
  918. iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o $NIC -j MASQUERADE
  919. iptables -D INPUT -i tun0 -j ACCEPT
  920. iptables -D FORWARD -i $NIC -o tun0 -j ACCEPT
  921. iptables -D FORWARD -i tun0 -o $NIC -j ACCEPT
  922. iptables -D INPUT -i $NIC -p $PROTOCOL --dport $PORT -j ACCEPT" >/etc/iptables/rm-openvpn-rules.sh
  923. if [[ $IPV6_SUPPORT == 'y' ]]; then
  924. echo "ip6tables -t nat -D POSTROUTING -s fd42:42:42:42::/112 -o $NIC -j MASQUERADE
  925. ip6tables -D INPUT -i tun0 -j ACCEPT
  926. ip6tables -D FORWARD -i $NIC -o tun0 -j ACCEPT
  927. ip6tables -D FORWARD -i tun0 -o $NIC -j ACCEPT
  928. ip6tables -D INPUT -i $NIC -p $PROTOCOL --dport $PORT -j ACCEPT" >>/etc/iptables/rm-openvpn-rules.sh
  929. fi
  930. chmod +x /etc/iptables/add-openvpn-rules.sh
  931. chmod +x /etc/iptables/rm-openvpn-rules.sh
  932. # Handle the rules via a systemd script
  933. echo "[Unit]
  934. Description=iptables rules for OpenVPN
  935. Before=network-online.target
  936. Wants=network-online.target
  937. [Service]
  938. Type=oneshot
  939. ExecStart=/etc/iptables/add-openvpn-rules.sh
  940. ExecStop=/etc/iptables/rm-openvpn-rules.sh
  941. RemainAfterExit=yes
  942. [Install]
  943. WantedBy=multi-user.target" >/etc/systemd/system/iptables-openvpn.service
  944. # Enable service and apply rules
  945. systemctl daemon-reload
  946. systemctl enable iptables-openvpn
  947. systemctl start iptables-openvpn
  948. # If the server is behind a NAT, use the correct IP address for the clients to connect to
  949. if [[ $ENDPOINT != "" ]]; then
  950. IP=$ENDPOINT
  951. fi
  952. # client-template.txt is created so we have a template to add further users later
  953. echo "client" >/etc/openvpn/client-template.txt
  954. if [[ $PROTOCOL == 'udp' ]]; then
  955. echo "proto udp" >>/etc/openvpn/client-template.txt
  956. echo "explicit-exit-notify" >>/etc/openvpn/client-template.txt
  957. elif [[ $PROTOCOL == 'tcp' ]]; then
  958. echo "proto tcp-client" >>/etc/openvpn/client-template.txt
  959. fi
  960. echo "remote $IP $PORT
  961. dev tun
  962. resolv-retry infinite
  963. nobind
  964. persist-key
  965. persist-tun
  966. remote-cert-tls server
  967. verify-x509-name $SERVER_NAME name
  968. auth $HMAC_ALG
  969. auth-nocache
  970. cipher $CIPHER
  971. tls-client
  972. tls-version-min 1.2
  973. tls-cipher $CC_CIPHER
  974. ignore-unknown-option block-outside-dns
  975. setenv opt block-outside-dns # Prevent Windows 10 DNS leak
  976. verb 3" >>/etc/openvpn/client-template.txt
  977. if [[ $COMPRESSION_ENABLED == "y" ]]; then
  978. echo "compress $COMPRESSION_ALG" >>/etc/openvpn/client-template.txt
  979. fi
  980. # Generate the custom client.ovpn
  981. newClient
  982. echo "If you want to add more clients, you simply need to run this script another time!"
  983. }
  984. function newClient() {
  985. echo ""
  986. echo "Tell me a name for the client."
  987. echo "The name must consist of alphanumeric character. It may also include an underscore or a dash."
  988. until [[ $CLIENT =~ ^[a-zA-Z0-9_-]+$ ]]; do
  989. read -rp "Client name: " -e CLIENT
  990. done
  991. echo ""
  992. echo "Do you want to protect the configuration file with a password?"
  993. echo "(e.g. encrypt the private key with a password)"
  994. echo " 1) Add a passwordless client"
  995. echo " 2) Use a password for the client"
  996. until [[ $PASS =~ ^[1-2]$ ]]; do
  997. read -rp "Select an option [1-2]: " -e -i 1 PASS
  998. done
  999. CLIENTEXISTS=$(tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep -c -E "/CN=$CLIENT\$")
  1000. if [[ $CLIENTEXISTS == '1' ]]; then
  1001. echo ""
  1002. echo "The specified client CN was already found in easy-rsa, please choose another name."
  1003. exit
  1004. else
  1005. cd /etc/openvpn/easy-rsa/ || return
  1006. case $PASS in
  1007. 1)
  1008. EASYRSA_CERT_EXPIRE=3650 ./easyrsa --batch build-client-full "$CLIENT" nopass
  1009. ;;
  1010. 2)
  1011. echo "⚠️ You will be asked for the client password below ⚠️"
  1012. EASYRSA_CERT_EXPIRE=3650 ./easyrsa --batch build-client-full "$CLIENT"
  1013. ;;
  1014. esac
  1015. echo "Client $CLIENT added."
  1016. fi
  1017. # Home directory of the user, where the client configuration will be written
  1018. if [ -e "/home/${CLIENT}" ]; then
  1019. # if $1 is a user name
  1020. homeDir="/home/${CLIENT}"
  1021. elif [ "${SUDO_USER}" ]; then
  1022. # if not, use SUDO_USER
  1023. if [ "${SUDO_USER}" == "root" ]; then
  1024. # If running sudo as root
  1025. homeDir="/root"
  1026. else
  1027. homeDir="/home/${SUDO_USER}"
  1028. fi
  1029. else
  1030. # if not SUDO_USER, use /root
  1031. homeDir="/root"
  1032. fi
  1033. # Determine if we use tls-auth or tls-crypt
  1034. if grep -qs "^tls-crypt" /etc/openvpn/server.conf; then
  1035. TLS_SIG="1"
  1036. elif grep -qs "^tls-auth" /etc/openvpn/server.conf; then
  1037. TLS_SIG="2"
  1038. fi
  1039. # Generates the custom client.ovpn
  1040. cp /etc/openvpn/client-template.txt "$homeDir/$CLIENT.ovpn"
  1041. {
  1042. echo "<ca>"
  1043. cat "/etc/openvpn/easy-rsa/pki/ca.crt"
  1044. echo "</ca>"
  1045. echo "<cert>"
  1046. awk '/BEGIN/,/END CERTIFICATE/' "/etc/openvpn/easy-rsa/pki/issued/$CLIENT.crt"
  1047. echo "</cert>"
  1048. echo "<key>"
  1049. cat "/etc/openvpn/easy-rsa/pki/private/$CLIENT.key"
  1050. echo "</key>"
  1051. case $TLS_SIG in
  1052. 1)
  1053. echo "<tls-crypt>"
  1054. cat /etc/openvpn/tls-crypt.key
  1055. echo "</tls-crypt>"
  1056. ;;
  1057. 2)
  1058. echo "key-direction 1"
  1059. echo "<tls-auth>"
  1060. cat /etc/openvpn/tls-auth.key
  1061. echo "</tls-auth>"
  1062. ;;
  1063. esac
  1064. } >>"$homeDir/$CLIENT.ovpn"
  1065. echo ""
  1066. echo "The configuration file has been written to $homeDir/$CLIENT.ovpn."
  1067. echo "Download the .ovpn file and import it in your OpenVPN client."
  1068. exit 0
  1069. }
  1070. function revokeClient() {
  1071. NUMBEROFCLIENTS=$(tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep -c "^V")
  1072. if [[ $NUMBEROFCLIENTS == '0' ]]; then
  1073. echo ""
  1074. echo "You have no existing clients!"
  1075. exit 1
  1076. fi
  1077. echo ""
  1078. echo "Select the existing client certificate you want to revoke"
  1079. tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
  1080. until [[ $CLIENTNUMBER -ge 1 && $CLIENTNUMBER -le $NUMBEROFCLIENTS ]]; do
  1081. if [[ $CLIENTNUMBER == '1' ]]; then
  1082. read -rp "Select one client [1]: " CLIENTNUMBER
  1083. else
  1084. read -rp "Select one client [1-$NUMBEROFCLIENTS]: " CLIENTNUMBER
  1085. fi
  1086. done
  1087. CLIENT=$(tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$CLIENTNUMBER"p)
  1088. cd /etc/openvpn/easy-rsa/ || return
  1089. ./easyrsa --batch revoke "$CLIENT"
  1090. EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
  1091. rm -f /etc/openvpn/crl.pem
  1092. cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem
  1093. chmod 644 /etc/openvpn/crl.pem
  1094. find /home/ -maxdepth 2 -name "$CLIENT.ovpn" -delete
  1095. rm -f "/root/$CLIENT.ovpn"
  1096. sed -i "/^$CLIENT,.*/d" /etc/openvpn/ipp.txt
  1097. cp /etc/openvpn/easy-rsa/pki/index.txt{,.bk}
  1098. echo ""
  1099. echo "Certificate for client $CLIENT revoked."
  1100. }
  1101. function removeUnbound() {
  1102. # Remove OpenVPN-related config
  1103. sed -i '/include: \/etc\/unbound\/openvpn.conf/d' /etc/unbound/unbound.conf
  1104. rm /etc/unbound/openvpn.conf
  1105. until [[ $REMOVE_UNBOUND =~ (y|n) ]]; do
  1106. echo ""
  1107. echo "If you were already using Unbound before installing OpenVPN, I removed the configuration related to OpenVPN."
  1108. read -rp "Do you want to completely remove Unbound? [y/n]: " -e REMOVE_UNBOUND
  1109. done
  1110. if [[ $REMOVE_UNBOUND == 'y' ]]; then
  1111. # Stop Unbound
  1112. systemctl stop unbound
  1113. if [[ $OS =~ (debian|ubuntu) ]]; then
  1114. apt-get remove --purge -y unbound
  1115. elif [[ $OS == 'arch' ]]; then
  1116. pacman --noconfirm -R unbound
  1117. elif [[ $OS =~ (centos|amzn|oracle) ]]; then
  1118. yum remove -y unbound
  1119. elif [[ $OS == 'fedora' ]]; then
  1120. dnf remove -y unbound
  1121. fi
  1122. rm -rf /etc/unbound/
  1123. echo ""
  1124. echo "Unbound removed!"
  1125. else
  1126. systemctl restart unbound
  1127. echo ""
  1128. echo "Unbound wasn't removed."
  1129. fi
  1130. }
  1131. function removeOpenVPN() {
  1132. echo ""
  1133. read -rp "Do you really want to remove OpenVPN? [y/n]: " -e -i n REMOVE
  1134. if [[ $REMOVE == 'y' ]]; then
  1135. # Get OpenVPN port from the configuration
  1136. PORT=$(grep '^port ' /etc/openvpn/server.conf | cut -d " " -f 2)
  1137. PROTOCOL=$(grep '^proto ' /etc/openvpn/server.conf | cut -d " " -f 2)
  1138. # Stop OpenVPN
  1139. if [[ $OS =~ (fedora|arch|centos|oracle) ]]; then
  1140. systemctl disable openvpn-server@server
  1141. systemctl stop openvpn-server@server
  1142. # Remove customised service
  1143. rm /etc/systemd/system/openvpn-server@.service
  1144. elif [[ $OS == "ubuntu" ]] && [[ $VERSION_ID == "16.04" ]]; then
  1145. systemctl disable openvpn
  1146. systemctl stop openvpn
  1147. else
  1148. systemctl disable openvpn@server
  1149. systemctl stop openvpn@server
  1150. # Remove customised service
  1151. rm /etc/systemd/system/openvpn\@.service
  1152. fi
  1153. # Remove the iptables rules related to the script
  1154. systemctl stop iptables-openvpn
  1155. # Cleanup
  1156. systemctl disable iptables-openvpn
  1157. rm /etc/systemd/system/iptables-openvpn.service
  1158. systemctl daemon-reload
  1159. rm /etc/iptables/add-openvpn-rules.sh
  1160. rm /etc/iptables/rm-openvpn-rules.sh
  1161. # SELinux
  1162. if hash sestatus 2>/dev/null; then
  1163. if sestatus | grep "Current mode" | grep -qs "enforcing"; then
  1164. if [[ $PORT != '1194' ]]; then
  1165. semanage port -d -t openvpn_port_t -p "$PROTOCOL" "$PORT"
  1166. fi
  1167. fi
  1168. fi
  1169. if [[ $OS =~ (debian|ubuntu) ]]; then
  1170. apt-get remove --purge -y openvpn
  1171. if [[ -e /etc/apt/sources.list.d/openvpn.list ]]; then
  1172. rm /etc/apt/sources.list.d/openvpn.list
  1173. apt-get update
  1174. fi
  1175. elif [[ $OS == 'arch' ]]; then
  1176. pacman --noconfirm -R openvpn
  1177. elif [[ $OS =~ (centos|amzn|oracle) ]]; then
  1178. yum remove -y openvpn
  1179. elif [[ $OS == 'fedora' ]]; then
  1180. dnf remove -y openvpn
  1181. fi
  1182. # Cleanup
  1183. find /home/ -maxdepth 2 -name "*.ovpn" -delete
  1184. find /root/ -maxdepth 1 -name "*.ovpn" -delete
  1185. rm -rf /etc/openvpn
  1186. rm -rf /usr/share/doc/openvpn*
  1187. rm -f /etc/sysctl.d/99-openvpn.conf
  1188. rm -rf /var/log/openvpn
  1189. # Unbound
  1190. if [[ -e /etc/unbound/openvpn.conf ]]; then
  1191. removeUnbound
  1192. fi
  1193. echo ""
  1194. echo "OpenVPN removed!"
  1195. else
  1196. echo ""
  1197. echo "Removal aborted!"
  1198. fi
  1199. }
  1200. function manageMenu() {
  1201. echo "Welcome to OpenVPN-install!"
  1202. echo "The git repository is available at: https://github.com/angristan/openvpn-install"
  1203. echo ""
  1204. echo "It looks like OpenVPN is already installed."
  1205. echo ""
  1206. echo "What do you want to do?"
  1207. echo " 1) Add a new user"
  1208. echo " 2) Revoke existing user"
  1209. echo " 3) Remove OpenVPN"
  1210. echo " 4) Exit"
  1211. until [[ $MENU_OPTION =~ ^[1-4]$ ]]; do
  1212. read -rp "Select an option [1-4]: " MENU_OPTION
  1213. done
  1214. case $MENU_OPTION in
  1215. 1)
  1216. newClient
  1217. ;;
  1218. 2)
  1219. revokeClient
  1220. ;;
  1221. 3)
  1222. removeOpenVPN
  1223. ;;
  1224. 4)
  1225. exit 0
  1226. ;;
  1227. esac
  1228. }
  1229. # Check for root, TUN, OS...
  1230. initialCheck
  1231. # Check if OpenVPN is already installed
  1232. if [[ -e /etc/openvpn/server.conf && $AUTO_INSTALL != "y" ]]; then
  1233. manageMenu
  1234. else
  1235. installOpenVPN
  1236. fi