public inbox for ipfire-scm@lists.ipfire.org
 help / color / mirror / Atom feed
From: Michael Tremer <git@ipfire.org>
To: ipfire-scm@lists.ipfire.org
Subject: [git.ipfire.org] IPFire 2.x development tree branch, next, updated. c5ecfbe3f1cb1adc4d8ad04c97a5d749dd5a3f1a
Date: Tue, 15 Jul 2025 09:57:31 +0000 (UTC)	[thread overview]
Message-ID: <4bhF3c51DCz2xfL@people01.haj.ipfire.org> (raw)

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "IPFire 2.x development tree".

The branch, next has been updated
       via  c5ecfbe3f1cb1adc4d8ad04c97a5d749dd5a3f1a (commit)
       via  231f939586d8ec1d72f654175b549859e59f105b (commit)
       via  fa429bcca8f156125181667fba75b2dfd13c7281 (commit)
       via  3bbf7b6e2919bf054af1d6c924522f889142ba91 (commit)
       via  eed199788837a54f739d567afe225abe02b0012f (commit)
       via  56400c89b82ecde90befe4fdda1027cfca707f03 (commit)
       via  5aebc354310a6cc3b9e9ade5cba02e151c1e6756 (commit)
       via  8ff821076e5bd610e747fef4b5c32eae3e744021 (commit)
       via  8e58e852163e636f4edf99a6c6419a8e3330113a (commit)
       via  07c05baff8f4c76d00dcbe9d6a120330131bb4ea (commit)
       via  3a9b321e3afc6cdbc0eb355d626f2a8fe8db3ce3 (commit)
       via  829d3f4f617c6bfcb2de7a178a171dec7a28a49f (commit)
       via  ed66fe66298734b0ecde91ff478eb814f8b0a099 (commit)
       via  26034a80ffbaafcb78e6514868159a561594cf1f (commit)
       via  ffe75e4767846f72bac49db6a2ba7274905d8d9d (commit)
       via  5f00c4dd53f403a8fd9c1f044ab1edd21a11a75d (commit)
       via  805eb6c1d6244887301fdc5414fafac420404a44 (commit)
       via  657998956d6ac7943d3ff3f6a9c65111bb3dcba6 (commit)
       via  693a13928d95fa3e6d73c841f70b4f3eec9d78e8 (commit)
       via  6d1abf3856ce9908089662cd35552f74ebafb941 (commit)
       via  956a69fdbeefbb681b3f6a76d3aedaae4f6d1539 (commit)
       via  c5c19b5e0cee738a9adae9805133725b5f181892 (commit)
       via  77e2d1bfc81072d6958d709e083aad480ded1814 (commit)
       via  3c508e008fc3b1395123d4e4a57b6a4a18c27041 (commit)
       via  5acb54c2679e8140372f56de2078463c2467ecff (commit)
       via  eb1b0ed1bf60f211d1f7da446542680f7f07e1c1 (commit)
       via  1b59f600e04aebd812026a4870fab2b7dd91043e (commit)
       via  e85939b2e0a9d6dd8522384459549452e4ee45fb (commit)
       via  0ad27c8f9a59c171319d14b958fca6ecd6b43023 (commit)
       via  d447db574723bcf98b2655e1b24af58e1be45ab1 (commit)
       via  3b100d3ad98ed5c51b2cccb8c050f5c798cf1a83 (commit)
       via  599e85983e63ff933f7d7a621a101f0af5729b60 (commit)
       via  ea1a3a5afa75a402d13705627ddd16bce096a802 (commit)
       via  0fc1af8a4adfa93685808e4ddf1a2be4c03ecb76 (commit)
       via  8f3b80cc4cb650b0ac49dca10ee441aeaef7338f (commit)
       via  3aec750ad797be05abee92044d90c2cbfb0e0a8e (commit)
       via  b13fb3dfc4ee6bdafe1ea3b38418f01fb6d90ddb (commit)
       via  c98529a671cb519e8dfb09d922cd20fdac398de5 (commit)
       via  c5d891d672ede1eda988f931977bbf408a1ddccc (commit)
       via  57f95cc2ea0f06336f2c0cbad5d65cb57ae3dab1 (commit)
       via  2649f62b5336d32725e4d5e2e0ad8972daefdca2 (commit)
       via  0bc717f598bbe9a3fa66a05ec8af76baf36c703d (commit)
       via  5b41f47b8ee302b86295aa5a3917037c6ab05fd3 (commit)
       via  6aff5b8104cc55d36b2446c328cb74f821b76ecb (commit)
       via  2271d043c4d62eb30876b60aec8f1150e8897ffa (commit)
       via  460942d7ed28ebf8c7727faa6321b63ee1c56964 (commit)
       via  b4b89379ab94eff031b0b02253fe027897861122 (commit)
       via  29097cef3ffc786a7b1ef3d99ae6f9e0f43f2f55 (commit)
       via  e3834fd8376e7a00be156549bf6c7b7ea710ffa4 (commit)
       via  c71aa190c8b571f98bfede8e0c96a67e5fcb8a03 (commit)
       via  decc7e0c4a7f813687fed5dc75995a6f0f4ff59a (commit)
       via  285be5bb34742be60a01f9eb17e56c0a5584c75a (commit)
       via  7d5d319b5075595c35d99b06b008b4994e7ce7c4 (commit)
       via  a188dd85fe083e9b6fd8f0ddf7687350ee5ed40c (commit)
       via  057f781b87d87eda6abf9df12d41e0abbcb3dcb8 (commit)
       via  dcbafa72e6fde4eecb4b18411aaf1008fbc7acf6 (commit)
       via  cba980f4b369dbd1e745f944c9c2eaa7791c2702 (commit)
       via  c33a0374a53968bc9cfab5f21b18ecf8619111e7 (commit)
       via  9b2035a8265e58fd15a329c52301ba28860985c8 (commit)
       via  f560e558d839b4d007d8a8d03f484ca36304c7d1 (commit)
       via  2862417617ab134600c18ebdfccef0288f68d506 (commit)
       via  fe5e31568be0758ec27b12a87f75640bc1bef813 (commit)
       via  c620343fe4a890e5e497c6a7696d1382485e9467 (commit)
       via  9edd392855a89de1ab9420a56192db7259eb50b5 (commit)
       via  7a28cc59aee870bcee3ec59928f694a8531e5e11 (commit)
       via  364a2b619ce08f85b7dd332e9d15e7177e3b5ce2 (commit)
       via  f5a05cdb55bde74b9f98036b12d808e630fa6961 (commit)
       via  c0ef1cf560af98f17fcfdee13b7ff3b533c029fe (commit)
       via  4c85492195a84146a0c1908f709cf0b566b35a22 (commit)
       via  a78cc8d035ef777fa04d9259ef6809841b04394f (commit)
       via  0a3766e0c68e6b7a43781d0643c2f726ec147b34 (commit)
       via  1e495925985bb4250352c041a131764b8bdc73a3 (commit)
       via  2241dbeff064dc5ece2d7c5988dbed69d2b87603 (commit)
       via  befe483f8301b6ef2b59da742ca18946b21f13b4 (commit)
       via  86365ab34da492a0b7de928376dab86d5879b0b7 (commit)
       via  37af5ae84d361ee9eb346e53ea7c185dff2ca406 (commit)
       via  bb192daff6d8fb856c8eab66cadace15cf3a97aa (commit)
       via  23fd2f1efbaa843c4253506de416200145ea5fe7 (commit)
       via  fbbb8e4508fb0aa077eb7a68e24274b49057c3a7 (commit)
       via  d3af28a489ff1bd4601b031069681431efc73818 (commit)
       via  3ad7c624e960227361847927e9d5bc9d968af1a7 (commit)
       via  cee76ccca3b8420363f61c17baa05bdea6136e49 (commit)
       via  3cdb4766fb6cbbc4c7245ff7edf571f4da300814 (commit)
       via  ec4de6703d6715e12b6113bd07fb0e2fc9b77ae6 (commit)
       via  1b81e5e2d306c5004bd29df752a8c02aa3cc21bf (commit)
       via  1eea39ff44cc981a29cc2a6d940a7cf1c74b3b4e (commit)
       via  a6cb61553527bb700cc7960ab30d6644af17fffd (commit)
       via  d8fa0cea30ed2b83d6353a4f432ee8f6b0c8c258 (commit)
       via  fdcd1daa197f22d90c35eae6c86dd2a99a8ad4f3 (commit)
       via  04b453725355aec3f440249b4a0c7e0595b9069a (commit)
       via  41c81273c8681cd2410f1171fd91d696a6fe743d (commit)
       via  a25d5d3ab1fbd486d91f967dfab3d3fa9e8c2a98 (commit)
       via  fb171334fd2482471c5b8cc334c0369ee2fd7bc9 (commit)
       via  2bb7a36a8f7623bbd5aeb2ee2e4dbba2485d1725 (commit)
       via  1e28ce55ff6b87f6aa207b01403801ab0d480090 (commit)
       via  e2120486c7bb14cd579560c1687f8cad5b449774 (commit)
       via  60caf9635d0515d4aa73913d6945bf956de0256b (commit)
       via  fb10f9949011fae5d0f2101602e443b3d380f8ff (commit)
       via  bfa6d0740ec7b12468ba03547b2c5be3a9a2bd42 (commit)
       via  07481d357af0118e1aaf88d46c00b758419606c3 (commit)
       via  b769ba05e7f8fa2ece154e8eb9b37f1603276f01 (commit)
       via  e017336a1f61cf6818afbba143fd5221973747e4 (commit)
       via  cd1f918e4dce1694bb0449afbe42c02c585b0b21 (commit)
       via  fe09cf897a725783e2be31360a785a878dd5629c (commit)
       via  d7923ad1556c5d75c0a488b48bcb5c786e618055 (commit)
       via  ab5af7d868b30eb062e456a9482b1a6d3dddc571 (commit)
       via  08837a72823efbb01f00b92b901e01fe87393a71 (commit)
       via  74eac5db4937392ba13ff05d60edd8b222417839 (commit)
       via  f990fe0142d8ddaf05f2aae3a408ac001721c273 (commit)
       via  7f5f1321128d4bd206fca4c0c6024bfd42260b6c (commit)
       via  7b4a35c98a4b098872a6a44b0817540b3164f1f1 (commit)
       via  a049b157b848bfb0dbbccc582f1307e366d52bee (commit)
       via  8a0868594526403a802c51151882dc887c446576 (commit)
       via  2208a0f85f966981acb11a17f739e9a11c53a427 (commit)
       via  963b71bfb5efc53f1eda90010e0651baef5b29e4 (commit)
       via  50e83cf2b1c441364bbc2718a8bdebed7219232e (commit)
       via  5fb0b119e5bfbbb1d2daabe45a2e5225b6de7212 (commit)
       via  ef027014d9c03b2c108ac02f16f7175b3c6da8e6 (commit)
       via  7f876fd24a854f1dfd90580b5586dcdae41e6ce2 (commit)
       via  a19e8621a3e70ddd9c72477f88ed71c3b24456e6 (commit)
       via  a04af768608c933a80ec45c819815e3eb0e5888b (commit)
       via  1e716201e2cc6572b52b4e274f169be681a2d625 (commit)
       via  954bd9dfdee4e1cff5056b433d12fb21d6531372 (commit)
       via  a10f3d5ac156f9c1b81b977ae508be525b52f421 (commit)
       via  d7cb4fa910e3cb581b00043219edc449b4c9ad75 (commit)
       via  cac18c9ca30881f90074d6efcc4039a1348215e6 (commit)
       via  2024b2a09f462794afa39d89af82c49e42a66889 (commit)
       via  92460a7c047778a6e152e019f047990fe399b711 (commit)
       via  42413182596203b9a2bbcf8f5cec73426560bc7f (commit)
       via  0187917c729bf75909b777d7254dbce9314fc3a7 (commit)
       via  2666a8072da5a10bd01c39e265234036f95fc18c (commit)
       via  19310ac789b5c115da5e38de698802bcf0d39af1 (commit)
       via  994e22d87a5e3ce3e61872b26dfd02f13fd2ed5c (commit)
       via  747386d4fbc8b2ed58707ff24a909b5dc2c72bef (commit)
      from  c374391a112fd4ac6508d246442eac88ae111da3 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit c5ecfbe3f1cb1adc4d8ad04c97a5d749dd5a3f1a
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Jul 15 09:57:16 2025 +0000

    core197: Ship OpenVPN changes
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 231f939586d8ec1d72f654175b549859e59f105b
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Jul 8 10:49:47 2025 +0200

    openvpn: Ignore existing PID files when starting processes
    
    This is all not very organised and tidy. The init process seems to be
    too cautious if there is a PID file left but there should not be any
    harm in trying to start the same process twice when in doubt because
    after all only one can bind to the same port at a time.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit fa429bcca8f156125181667fba75b2dfd13c7281
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Jul 8 10:44:30 2025 +0200

    ovpnmain.cgi: Accept an empty value for ENABLED
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 3bbf7b6e2919bf054af1d6c924522f889142ba91
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Jul 8 10:42:36 2025 +0200

    ovpnmain.cgi: Fix broken headline in N2N crypto section
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit eed199788837a54f739d567afe225abe02b0012f
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Jul 8 10:38:44 2025 +0200

    Revert "ovpnmain.cgi: Remove yet another "if (1)" statement"
    
    This reverts commit 0dcafefb694d4e1ebef317f4d45f68216685ff25.
    
    Removing this breaks creating N2N connections and I don't think there is
    a way to fix this all properly without a major rewrite.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 56400c89b82ecde90befe4fdda1027cfca707f03
Author: Adolf Belka <adolf.belka@ipfire.org>
Date:   Mon Jun 30 11:00:30 2025 +0200

    services.cgi: Openvpn-2.6 rebase fix pid name for services page
    
    Signed-off-by: Adolf Belka <adolf.belka@ipfire.org>
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 5aebc354310a6cc3b9e9ade5cba02e151c1e6756
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Mon Jun 30 10:41:35 2025 +0200

    openvpn: Fix typo in initscript
    
    This prevented the authenticator from being shut down gracefully.
    
      https://lists.ipfire.org/development/1396727E-BF73-4015-B853-B3F854806B28@ipfire.org/T/#m41dd73643dc6fa0dd6d187f59f72277f9c5d072f
    
    Reported-by: Adolf Belka <adolf.belka@ipfire.org>
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 8ff821076e5bd610e747fef4b5c32eae3e744021
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Thu Jun 19 16:49:22 2025 +0200

    ovpnmain.cgi: Accept empty input for ENABLED
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 8e58e852163e636f4edf99a6c6419a8e3330113a
Author: Stefan Schantl <stefan.schantl@ipfire.org>
Date:   Thu Jun 19 16:47:50 2025 +0200

    ovpnmain.cgi: Make checkboxes unselectable
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 07c05baff8f4c76d00dcbe9d6a120330131bb4ea
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Jun 3 17:04:50 2025 +0200

    ovpnmain.cgi: Only load status when the server is running
    
    Otherwise we would show the status if the service is no longer running
    and show clients as connected which have only been connected when the
    server was stopped.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 3a9b321e3afc6cdbc0eb355d626f2a8fe8db3ce3
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Jun 3 16:21:12 2025 +0200

    ovpnmain.cgi: Fix reading the current status file again
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 829d3f4f617c6bfcb2de7a178a171dec7a28a49f
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Jun 3 16:10:53 2025 +0200

    ovpnmain.cgi: Remove more dead code
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit ed66fe66298734b0ecde91ff478eb814f8b0a099
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Jun 3 16:08:45 2025 +0200

    ovpnmain.cgi: Fix path to the RW PID file
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 26034a80ffbaafcb78e6514868159a561594cf1f
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Jun 3 16:06:03 2025 +0200

    ovpnmain.cgi: Use the helper binary to read the status log
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit ffe75e4767846f72bac49db6a2ba7274905d8d9d
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Jun 3 12:44:33 2025 +0200

    ovpnmain.cgi: Log a better message if the RW log file could not be opened
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 5f00c4dd53f403a8fd9c1f044ab1edd21a11a75d
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Jun 3 12:40:38 2025 +0200

    ovpnmain.cgi: Tell the server the subnet in the old-fashioned way
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 805eb6c1d6244887301fdc5414fafac420404a44
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Jun 3 12:33:44 2025 +0200

    ovpnmain.cgi: Remove some dead code
    
    This prevented creating new connections and was never being used at all.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 657998956d6ac7943d3ff3f6a9c65111bb3dcba6
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Jun 3 12:27:28 2025 +0200

    Revert "CSS: Make text/number inputs 100% wide, too"
    
    This reverts commit f9beaa17f22a191919b2982511d4a4598ffcf81e.
    
    This seems to break major parts of the layout on several pages.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 693a13928d95fa3e6d73c841f70b4f3eec9d78e8
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Jun 3 12:25:38 2025 +0200

    CSS: Fix merge error
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 6d1abf3856ce9908089662cd35552f74ebafb941
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Jun 3 09:27:03 2025 +0000

    openvpn: Update to 2.6.14
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 956a69fdbeefbb681b3f6a76d3aedaae4f6d1539
Author: Adolf Belka <adolf.belka@ipfire.org>
Date:   Sun Dec 8 12:23:30 2024 +0100

    openvpn: Update to version 2.6.12
    
    Signed-off-by: Adolf Belka <adolf.belka@ipfire.org>
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit c5c19b5e0cee738a9adae9805133725b5f181892
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 16 15:03:13 2024 +0200

    ovpnmain.cgi: Implement a better way to set defaults
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 77e2d1bfc81072d6958d709e083aad480ded1814
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 16 14:18:39 2024 +0200

    ovpnmain.cgi: Load the main settings just once
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 3c508e008fc3b1395123d4e4a57b6a4a18c27041
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 16 14:13:32 2024 +0200

    ovpnmain.cgi: Use the same hash for the configuration like everywhere else
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 5acb54c2679e8140372f56de2078463c2467ecff
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 16 14:01:31 2024 +0200

    ovpnmain.cgi: Restart instead of reload
    
    The option to reload the server does not seem to work well. The running
    is process is performing a number of checks that make very little sense
    and PID files get written by the user that launches the process (i.e.
    root) instead of the user that the process is running as later on (i.e.
    nobody). Since there is no chance to keep any existing connections alive
    this way, we may just as well restart the service for now.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit eb1b0ed1bf60f211d1f7da446542680f7f07e1c1
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 16 14:00:35 2024 +0200

    openvpn-rw: Use a sensible name for the PID file
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 1b59f600e04aebd812026a4870fab2b7dd91043e
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 16 13:58:47 2024 +0200

    ovpnmain.cgi: Give the status log a more sensible name
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit e85939b2e0a9d6dd8522384459549452e4ee45fb
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 16 13:25:30 2024 +0200

    ovpnmain.cgi: Explicitly notify clients that the server is going down
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 0ad27c8f9a59c171319d14b958fca6ecd6b43023
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 16 13:20:02 2024 +0200

    i18n: Update note on the file format of the OpenVPN client configuration
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit d447db574723bcf98b2655e1b24af58e1be45ab1
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Thu Apr 11 22:29:09 2024 +0200

    ovpnmain.cgi: Refactor top table of adding/creating connections
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 3b100d3ad98ed5c51b2cccb8c050f5c798cf1a83
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Thu Apr 11 22:15:51 2024 +0200

    ovpnmain.cgi: Remove yet another "if (1)" statement
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 599e85983e63ff933f7d7a621a101f0af5729b60
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Thu Apr 11 22:10:23 2024 +0200

    ovpnmain.cgi: Refactor connection statistics page
    
    No functional changes
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit ea1a3a5afa75a402d13705627ddd16bce096a802
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Thu Apr 11 21:42:16 2024 +0200

    ovpnmain.cgi: Remove ns-cert-type server
    
    This option has been removed in OpenVPN 2.5. We do not support anything
    prior to that.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 0fc1af8a4adfa93685808e4ddf1a2be4c03ecb76
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Thu Apr 11 21:40:55 2024 +0200

    ovpnmain.cgi: Remove unnecessary client configuration options
    
    We should send the most minimal configuration so that we do not
    overwrite any sensible defaults.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 8f3b80cc4cb650b0ac49dca10ee441aeaef7338f
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Thu Apr 11 21:24:22 2024 +0200

    ovpnmain.cgi: Fix spacing in client configuration file
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 3aec750ad797be05abee92044d90c2cbfb0e0a8e
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Thu Apr 11 21:22:15 2024 +0200

    ovpnmain.cgi: Use LF only without CR for config files
    
    Fixes: #13355
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit b13fb3dfc4ee6bdafe1ea3b38418f01fb6d90ddb
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Thu Apr 11 21:20:01 2024 +0200

    ovpnmain.cgi: Remove the ZIP container around configuration files
    
    Since we can now include everything in one file, there is no need to put
    it in a ZIP container.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit c98529a671cb519e8dfb09d922cd20fdac398de5
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Thu Apr 11 21:12:54 2024 +0200

    ovpnmain.cgi: Remove the "insecure" client package
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit c5d891d672ede1eda988f931977bbf408a1ddccc
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Thu Apr 11 21:02:33 2024 +0200

    ovpnmain.cgi: Include the PKCS12 certificate on config export
    
    Before, OpenVPN did not support PKCS12 files in an embedded format. We
    extracted the key and the certificate in PEM format instead.
    
    This is no longer necessary and therefore we can simply include the
    file.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 57f95cc2ea0f06336f2c0cbad5d65cb57ae3dab1
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Apr 10 17:49:01 2024 +0200

    ovpnmain.cgi: Reindent generating the client configuration
    
    There are no functional changes.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 2649f62b5336d32725e4d5e2e0ad8972daefdca2
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Apr 10 17:14:07 2024 +0200

    ovpnmain.cgi: Refactor CCD pool configuration
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 0bc717f598bbe9a3fa66a05ec8af76baf36c703d
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Apr 10 15:52:06 2024 +0200

    ovpnmain.cgi: Remove code to restart a connection
    
    This could not be triggered.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 5b41f47b8ee302b86295aa5a3917037c6ab05fd3
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Apr 10 15:43:32 2024 +0200

    ovpnmain.cgi: Refactor the connection listing
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 6aff5b8104cc55d36b2446c328cb74f821b76ecb
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Apr 10 14:11:27 2024 +0200

    ovpnmain.cgi: Enable legacy provider for auths, too
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 2271d043c4d62eb30876b60aec8f1150e8897ffa
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Apr 10 14:03:30 2024 +0200

    ovpnmain.cgi: Load the OpenSSL legacy provider if required
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 460942d7ed28ebf8c7727faa6321b63ee1c56964
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Apr 10 12:55:47 2024 +0200

    ovpnmain.cgi: Move "ROUTE_PUSH" settings into the main settings file
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit b4b89379ab94eff031b0b02253fe027897861122
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Apr 10 12:34:45 2024 +0200

    ovpnmain.cgi: Fix checking custom routes
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 29097cef3ffc786a7b1ef3d99ae6f9e0f43f2f55
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 19:49:30 2024 +0200

    ovpnmain.cgi: Reload the server after changing advanced settings
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit e3834fd8376e7a00be156549bf6c7b7ea710ffa4
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 19:45:45 2024 +0200

    ovpnmain.cgi: Remove more unused variables
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit c71aa190c8b571f98bfede8e0c96a67e5fcb8a03
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 19:41:59 2024 +0200

    ovpnmain.cgi: Refactor the entire advanced settings page
    
    There are no functional changes.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit decc7e0c4a7f813687fed5dc75995a6f0f4ff59a
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 19:23:18 2024 +0200

    CSS: Don't make headings so skinny
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 285be5bb34742be60a01f9eb17e56c0a5584c75a
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 19:08:25 2024 +0200

    ovpnmain.cgi: Remove "additional configs"
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 7d5d319b5075595c35d99b06b008b4994e7ce7c4
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 19:04:58 2024 +0200

    ovpnmain.cgi: Remove client-to-client
    
    This is a potential security issue. See #13636.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit a188dd85fe083e9b6fd8f0ddf7687350ee5ed40c
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 19:02:22 2024 +0200

    ovpnmain.cgi: Hard-code keepalive packets
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 057f781b87d87eda6abf9df12d41e0abbcb3dcb8
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 18:58:51 2024 +0200

    ovpnmain.cgi: Hard-code "verb 3"
    
    There is no reason why users will need to change this.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit dcbafa72e6fde4eecb4b18411aaf1008fbc7acf6
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 18:54:30 2024 +0200

    ovpnmain.cgi: Improve wording for RW settings
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit cba980f4b369dbd1e745f944c9c2eaa7791c2702
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 18:38:26 2024 +0200

    initscripts: Manually load the tun module for OpenVPN
    
    The server cannot load the module itself.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit c33a0374a53968bc9cfab5f21b18ecf8619111e7
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 18:36:56 2024 +0200

    ovpnmain.cgi: Remove manual start/stop actions
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 9b2035a8265e58fd15a329c52301ba28860985c8
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 18:25:47 2024 +0200

    ovpnmain.cgi: Redesign the roadwarrior section
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit f560e558d839b4d007d8a8d03f484ca36304c7d1
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 18:25:11 2024 +0200

    CSS: Make text/number inputs 100% wide, too
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 2862417617ab134600c18ebdfccef0288f68d506
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 18:09:37 2024 +0200

    ovpnmain.cgi: Only allow removing X.509 when the server is not enabled
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit fe5e31568be0758ec27b12a87f75640bc1bef813
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 18:08:33 2024 +0200

    ovpnmain.cgi: Remove left-over code
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit c620343fe4a890e5e497c6a7696d1382485e9467
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 18:08:06 2024 +0200

    ovpnmain.cgi: Move destination port to advanced settings
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 9edd392855a89de1ab9420a56192db7259eb50b5
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 18:00:48 2024 +0200

    ovpnmain.cgi: Move MTU setting to advanced settings
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 7a28cc59aee870bcee3ec59928f694a8531e5e11
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 17:52:37 2024 +0200

    ovpnmain.cgi: Move protocol setting to advanced settings
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 364a2b619ce08f85b7dd332e9d15e7177e3b5ce2
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Apr 9 17:45:46 2024 +0200

    ovpnmain.cgi: Remove the old status indicator
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit f5a05cdb55bde74b9f98036b12d808e630fa6961
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sat Mar 23 20:09:34 2024 +0100

    vulnerabilities.cgi: Use section
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit c0ef1cf560af98f17fcfdee13b7ff3b533c029fe
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sat Mar 23 19:57:49 2024 +0100

    vulnerabilities.cgi: Use CSS to colour the table
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 4c85492195a84146a0c1908f709cf0b566b35a22
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sat Mar 23 19:12:26 2024 +0100

    web: Explain memory consumption
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit a78cc8d035ef777fa04d9259ef6809841b04394f
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sat Mar 23 19:06:31 2024 +0100

    tor.cgi: Use new service function
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 0a3766e0c68e6b7a43781d0643c2f726ec147b34
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sat Mar 23 19:00:49 2024 +0100

    CSS: Automatically stripe all tables
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 1e495925985bb4250352c041a131764b8bdc73a3
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sat Mar 23 18:42:13 2024 +0100

    web: Create a function to show the service status
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 2241dbeff064dc5ece2d7c5988dbed69d2b87603
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sat Mar 23 17:01:14 2024 +0100

    ovpnmain.cgi: Use global ethernet settings
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit befe483f8301b6ef2b59da742ca18946b21f13b4
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sat Mar 23 15:33:55 2024 +0100

    OpenVPN: Rename "Global Settings" to "Roadwarrior Settings"
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 86365ab34da492a0b7de928376dab86d5879b0b7
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sat Mar 23 15:32:36 2024 +0100

    make.sh: Update language files
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 37af5ae84d361ee9eb346e53ea7c185dff2ca406
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sat Mar 23 15:29:27 2024 +0100

    initscripts: Silence error messages when testing if a process is running
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit bb192daff6d8fb856c8eab66cadace15cf3a97aa
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sat Mar 23 15:03:36 2024 +0100

    openvpnctrl: Rewrite the entire thing
    
    This binary because a major headache as it has been changed so many
    times by so many people neglegting the code quality. Therefore, the
    logic has now been moved into initscripts and the binary changed so that
    it only serves as a SUID wrapper to call the initscripts.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 23fd2f1efbaa843c4253506de416200145ea5fe7
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sat Mar 23 15:00:18 2024 +0100

    initscripts: Call the initscript to create firewall rules
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit fbbb8e4508fb0aa077eb7a68e24274b49057c3a7
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sat Mar 23 14:57:19 2024 +0100

    initscripts: No longer restart OpenVPN when RED comes up/goes down
    
    This is probably a relic from when dial-up connections where on trend
    and systems were offline for long times of the day. Now, we should
    always be on and there is no need to restart all those services on a
    reconnect.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit d3af28a489ff1bd4601b031069681431efc73818
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sat Mar 23 14:43:46 2024 +0100

    openvpn-n2n: Implement deleting RRD databases
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 3ad7c624e960227361847927e9d5bc9d968af1a7
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sat Mar 23 14:39:30 2024 +0100

    openvpn: Add an initscript for N2N connections
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit cee76ccca3b8420363f61c17baa05bdea6136e49
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Thu Mar 21 18:08:31 2024 +0100

    openvpnctrl: Remove the stuff we no longer need
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 3cdb4766fb6cbbc4c7245ff7edf571f4da300814
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Thu Mar 21 18:05:51 2024 +0100

    initscripts: Start the OpenVPN Authenticator, too
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit ec4de6703d6715e12b6113bd07fb0e2fc9b77ae6
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Thu Mar 21 17:58:46 2024 +0100

    initscripts: Add an initscript for OpenVPN RW
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 1b81e5e2d306c5004bd29df752a8c02aa3cc21bf
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Thu Mar 21 16:51:39 2024 +0100

    firewall: Split OpenVPN INPUT chains for RW & N2N
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 1eea39ff44cc981a29cc2a6d940a7cf1c74b3b4e
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Thu Mar 21 16:47:21 2024 +0100

    ovpnmain.cgi: Remove option to enable on ORANGE/BLUE
    
    There is no point in not making this service available to any local
    networks when it always has to be reachable from the Internet.
    
    This still has to be reflected in the initscripts
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit a6cb61553527bb700cc7960ab30d6644af17fffd
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Mar 20 20:38:52 2024 +0100

    ovpnmain.cgi: Migrate to subnet topology
    
    For dynamic pools, this change is easy and does not require any extra
    steps. For CCD clients however, we need to update the configuration to
    replace the server IP address with the subnet mask.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit d8fa0cea30ed2b83d6353a4f432ee8f6b0c8c258
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Mar 20 17:34:00 2024 +0100

    ovpnmain.cgi: Create functions to read CCD client/server routes
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit fdcd1daa197f22d90c35eae6c86dd2a99a8ad4f3
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Mar 20 17:33:14 2024 +0100

    ovpnmain.cgi: Remove comment that a restart is required
    
    This is incorrect as we can change CCD data without restarting the
    server.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 04b453725355aec3f440249b4a0c7e0595b9069a
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Mar 20 17:20:16 2024 +0100

    ovpnmain.cgi: Refactor writing CCD files
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 41c81273c8681cd2410f1171fd91d696a6fe743d
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Mar 20 14:56:20 2024 +0100

    ovpnmain.cgi: Drop validdotmask()
    
    This is a totally braindead function that prevented some basic usability
    by using the more modern prefix notation. It simply checks if there is a
    freaking dot. Great!
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit a25d5d3ab1fbd486d91f967dfab3d3fa9e8c2a98
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Mar 20 14:45:14 2024 +0100

    ovpnmain.cgi: Drop hostsinnet
    
    This is no longer needed as we can use the function that lists all
    addresses that are in use and count them.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit fb171334fd2482471c5b8cc334c0369ee2fd7bc9
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Mar 20 14:42:27 2024 +0100

    ovpnmain.cgi: Refactor listing CCD addresses
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 2bb7a36a8f7623bbd5aeb2ee2e4dbba2485d1725
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Mar 20 12:32:22 2024 +0100

    ovpnmain.cgi: Refactor ccdmaxclients()
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 1e28ce55ff6b87f6aa207b01403801ab0d480090
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Mar 20 12:25:58 2024 +0100

    ovpnmain.cgi: Refactor modccnet()
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit e2120486c7bb14cd579560c1687f8cad5b449774
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Mar 20 12:12:00 2024 +0100

    ovpnmain.cgi: Refactor addccdnet()
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 60caf9635d0515d4aa73913d6945bf956de0256b
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Mar 20 11:36:23 2024 +0100

    ovpnmain.cgi: Move function to check CCD names here
    
    This was in general-functions.pl for some reason.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit fb10f9949011fae5d0f2101602e443b3d380f8ff
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Mar 20 11:33:16 2024 +0100

    ovpnmain.cgi: Refactor function to remove a static pool
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit bfa6d0740ec7b12468ba03547b2c5be3a9a2bd42
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Mar 20 11:21:58 2024 +0100

    ovpnmain.cgi: Remove enabled marker files
    
    Nothing is using these any more.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 07481d357af0118e1aaf88d46c00b758419606c3
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Mar 20 11:15:18 2024 +0100

    ovpnmain.cgi: Remove any left-over traces of DH replacement
    
    Since there is no way for the user to manipulate this any more, there is
    no point in checking and showing the DH parameters.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit b769ba05e7f8fa2ece154e8eb9b37f1603276f01
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Mar 20 11:12:37 2024 +0100

    ovpnmain.cgi: Remove excess whitespace
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit e017336a1f61cf6818afbba143fd5221973747e4
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Wed Mar 20 11:09:39 2024 +0100

    ovpnmain.cgi: Remove more dead code
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit cd1f918e4dce1694bb0449afbe42c02c585b0b21
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 20:44:18 2024 +0100

    ovpnmain.cgi: Force NCP on clients
    
    This change requires that all clients support NCP if they are set up
    with a new connection. Existing clients remain supported using the
    fallback cipher option.
    
    This will result that connections with OpenVPN <= 2.3 cannot be set up
    any more which is totally fine since that version is EOL.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit fe09cf897a725783e2be31360a785a878dd5629c
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 19:14:26 2024 +0000

    openvpn: Update to 2.6.9
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit d7923ad1556c5d75c0a488b48bcb5c786e618055
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 20:11:31 2024 +0100

    ovpnmain.cgi: Completely remove compression for RW clients
    
    We will use the "compress migrate" option which disables compression by
    default. If a client has been found that wants to use compression, the
    server will push "stub-v2" to disable it. If that does not work, the
    server might fall back to compression.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit ab5af7d868b30eb062e456a9482b1a6d3dddc571
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 19:32:50 2024 +0100

    ovpnmain.cgi: Implement cipher negotiation for RW clients
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 08837a72823efbb01f00b92b901e01fe87393a71
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 18:38:34 2024 +0100

    ovpnmain.cgi: Remove presetting removed options
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 74eac5db4937392ba13ff05d60edd8b222417839
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 18:37:45 2024 +0100

    ovpnmain.cgi: Remove dead code
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit f990fe0142d8ddaf05f2aae3a408ac001721c273
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 18:37:24 2024 +0100

    ovpnmain.cgi: Use SHA512 for hashing by default
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 7f5f1321128d4bd206fca4c0c6024bfd42260b6c
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 18:36:42 2024 +0100

    ovpnmain.cgi: Keep the fallback cipher disabled by default
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 7b4a35c98a4b098872a6a44b0817540b3164f1f1
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 18:32:25 2024 +0100

    ovpnmain.cgi: Allow to disable the fallback cipher
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit a049b157b848bfb0dbbccc582f1307e366d52bee
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 18:26:27 2024 +0100

    ovpnmain.cgi: Rename cipher selection to fallback cipher
    
    This is to keep ancient clients and clients that have NCP disabled
    happy.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 8a0868594526403a802c51151882dc887c446576
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 18:04:20 2024 +0100

    lang: Update because of OpenVPN changes
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 2208a0f85f966981acb11a17f739e9a11c53a427
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 18:02:17 2024 +0100

    CSS: Make all <select> and <textarea> use all available space
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 963b71bfb5efc53f1eda90010e0651baef5b29e4
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 17:57:39 2024 +0100

    ovpnmain.cgi: Fix the completely fucked table layout
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 50e83cf2b1c441364bbc2718a8bdebed7219232e
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 17:49:59 2024 +0100

    ovpnmain.cgi: Move the cryptographic options to the advanced page
    
    Since we don't want people play too much with these, we move them to the
    advanced settings page.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 5fb0b119e5bfbbb1d2daabe45a2e5225b6de7212
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 17:14:03 2024 +0100

    ovpnmain.cgi: Fix resetting compression setting
    
    The compression option was reset (disabled) when the Save button on the
    main was being clicked.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit ef027014d9c03b2c108ac02f16f7175b3c6da8e6
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 17:11:00 2024 +0100

    ovpnmain.cgi: Remove crypto error/warning boxes
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 7f876fd24a854f1dfd90580b5586dcdae41e6ce2
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 16:58:30 2024 +0100

    ovpnmain.cgi: Remove authorship comments
    
    These are not very useful.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit a19e8621a3e70ddd9c72477f88ed71c3b24456e6
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 16:51:29 2024 +0100

    ovpnmain.cgi: Don't mess with the OpenVPN status file
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit a04af768608c933a80ec45c819815e3eb0e5888b
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 16:44:02 2024 +0100

    ovpnmain.cgi: Move things that belong together together
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 1e716201e2cc6572b52b4e274f169be681a2d625
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 16:41:53 2024 +0100

    ovpnmain.cgi: Don't create CCD configuration files on every call
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 954bd9dfdee4e1cff5056b433d12fb21d6531372
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 16:39:21 2024 +0100

    ovpnmain.cgi: Reorganise loading external modules
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit a10f3d5ac156f9c1b81b977ae508be525b52f421
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 16:38:54 2024 +0100

    ovpnmain.cgi: Don't include lang.pl again when its already loaded in header.pl
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit d7cb4fa910e3cb581b00043219edc449b4c9ad75
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 16:38:19 2024 +0100

    ovpnmain.cgi: Don't load colours when they are already loaded in header.pl
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit cac18c9ca30881f90074d6efcc4039a1348215e6
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 16:34:51 2024 +0100

    ovpnmain.cgi: Remove unused variable hack
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 2024b2a09f462794afa39d89af82c49e42a66889
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 16:32:33 2024 +0100

    ovpnmain.cgi: Drop newcleanssldatabase()
    
    I have no idea why this was added when there is a function that does the
    same already. The remove function also had typos in the path which
    probably resulted in it not working very well.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 92460a7c047778a6e152e019f047990fe399b711
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 16:29:30 2024 +0100

    ovpnmain.cgi: Use the formatting function we already have
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 42413182596203b9a2bbcf8f5cec73426560bc7f
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 16:19:37 2024 +0100

    ovpnmain.cgi: Drop unused refresh code
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 0187917c729bf75909b777d7254dbce9314fc3a7
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 16:18:44 2024 +0100

    ovpnmain.cgi: Tidy up starting/restarting the RW server
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 2666a8072da5a10bd01c39e265234036f95fc18c
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 16:10:40 2024 +0100

    ovpnmain.cgi: Use default functions to check what subnets exist
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 19310ac789b5c115da5e38de698802bcf0d39af1
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 16:02:34 2024 +0100

    ovpnmain.cgi: Remove certificate warnings
    
    I believe that these don't really work and are always shown.
    Please see #13634.
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 994e22d87a5e3ce3e61872b26dfd02f13fd2ed5c
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 15:54:07 2024 +0100

    ovpnmain.cgi: Fix some whitespace issues
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 747386d4fbc8b2ed58707ff24a909b5dc2c72bef
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Mar 19 15:53:46 2024 +0100

    ovpnmain.cgi: Enable debugging
    
    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

-----------------------------------------------------------------------

Summary of changes:
 config/cfgroot/general-functions.pl                |   15 -
 config/cfgroot/header.pl                           |    4 +
 config/rootfiles/common/aarch64/initscripts        |   10 +-
 config/rootfiles/common/riscv64/initscripts        |   10 +-
 config/rootfiles/common/x86_64/initscripts         |   10 +-
 config/rootfiles/core/197/filelists/files          |   17 +
 .../{oldcore/100 => core/197}/filelists/openvpn    |    0
 config/rootfiles/core/197/update.sh                |    8 +
 doc/language_issues.de                             |   60 +-
 doc/language_issues.en                             |   70 +-
 doc/language_issues.es                             |   60 +-
 doc/language_issues.fr                             |   60 +-
 doc/language_issues.it                             |   60 +-
 doc/language_issues.nl                             |   60 +-
 doc/language_issues.pl                             |   62 +-
 doc/language_issues.ru                             |   60 +-
 doc/language_issues.tr                             |   60 +-
 doc/language_issues.tw                             |   60 +-
 doc/language_issues.zh                             |   60 +-
 doc/language_missings                              |  237 +-
 html/cgi-bin/ovpnmain.cgi                          | 3954 +++++++++-----------
 html/cgi-bin/services.cgi                          |    4 +-
 html/cgi-bin/tor.cgi                               |   25 +-
 html/cgi-bin/vulnerabilities.cgi                   |    4 +-
 html/html/themes/ipfire/include/css/style.css      |   20 +-
 langs/en/cgi-bin/en.pl                             |   38 +-
 lfs/initscripts                                    |    6 +
 lfs/openvpn                                        |    4 +-
 lfs/tor                                            |    2 +-
 src/initscripts/networking/red.down/10-ovpn        |    6 -
 src/initscripts/networking/red.up/50-ovpn          |    6 -
 src/initscripts/system/firewall                    |   14 +-
 src/initscripts/system/functions                   |    2 +-
 src/initscripts/system/openvpn-n2n                 |  372 ++
 .../{packages/dnsdist => system/openvpn-rw}        |   65 +-
 src/misc-progs/openvpnctrl.c                       |  786 +---
 36 files changed, 3159 insertions(+), 3132 deletions(-)
 copy config/rootfiles/{oldcore/100 => core/197}/filelists/openvpn (100%)
 delete mode 100644 src/initscripts/networking/red.down/10-ovpn
 delete mode 100644 src/initscripts/networking/red.up/50-ovpn
 create mode 100644 src/initscripts/system/openvpn-n2n
 copy src/initscripts/{packages/dnsdist => system/openvpn-rw} (64%)

Difference in files:
diff --git a/config/cfgroot/general-functions.pl b/config/cfgroot/general-functions.pl
index cc5d9fd812..33b5605e2e 100644
--- a/config/cfgroot/general-functions.pl
+++ b/config/cfgroot/general-functions.pl
@@ -758,21 +758,6 @@ sub validhostname
 	return 1;
 }
 
-sub validccdname
-{
-	# Checks a ccdname for letters, numbers and spaces
-        my $ccdname = $_[0];
-
-	# ccdname should be at least one character in length
-	# but no more than 63 characters
-	if (length ($ccdname) < 1 || length ($ccdname) > 63) {
-		return 0;}
-	# Only valid characters are a-z, A-Z, 0-9, space and -
-	if ($ccdname !~ /^[a-zA-Z0-9 -]*$/) {
-		return 0;}
-	return 1;
-}
-
 sub validdomainname
 {
 	my $part;
diff --git a/config/cfgroot/header.pl b/config/cfgroot/header.pl
index 48ca16996d..9492b467d0 100644
--- a/config/cfgroot/header.pl
+++ b/config/cfgroot/header.pl
@@ -985,6 +985,10 @@ EOF
 
 					<td class="text-right">
 						${mem}
+
+						<span title="$Lang::tr{'rss long'}">
+							$Lang::tr{'rss'}
+						</span>
 					</td>
 EOF
 
diff --git a/config/rootfiles/common/aarch64/initscripts b/config/rootfiles/common/aarch64/initscripts
index 12898701ab..1fd1f076f3 100644
--- a/config/rootfiles/common/aarch64/initscripts
+++ b/config/rootfiles/common/aarch64/initscripts
@@ -46,7 +46,6 @@ etc/rc.d/init.d/networking/orange
 etc/rc.d/init.d/networking/red
 #etc/rc.d/init.d/networking/red.down
 etc/rc.d/init.d/networking/red.down/10-ipsec
-etc/rc.d/init.d/networking/red.down/10-ovpn
 etc/rc.d/init.d/networking/red.down/10-static-routes
 etc/rc.d/init.d/networking/red.down/20-firewall
 etc/rc.d/init.d/networking/red.down/99-beep
@@ -62,7 +61,6 @@ etc/rc.d/init.d/networking/red.up/27-RS-squid
 etc/rc.d/init.d/networking/red.up/30-ddns
 #etc/rc.d/init.d/networking/red.up/35-guardian
 etc/rc.d/init.d/networking/red.up/50-ipsec
-etc/rc.d/init.d/networking/red.up/50-ovpn
 etc/rc.d/init.d/networking/red.up/60-collectd
 etc/rc.d/init.d/networking/red.up/98-leds
 etc/rc.d/init.d/networking/red.up/99-beep
@@ -70,6 +68,8 @@ etc/rc.d/init.d/networking/red.up/99-fireinfo
 etc/rc.d/init.d/networking/red.up/99-pakfire-update
 etc/rc.d/init.d/networking/wpa_supplicant.exe
 etc/rc.d/init.d/ntp
+etc/rc.d/init.d/openvpn-n2n
+etc/rc.d/init.d/openvpn-rw
 etc/rc.d/init.d/pakfire
 etc/rc.d/init.d/partresize
 etc/rc.d/init.d/rc
@@ -98,6 +98,8 @@ etc/rc.d/init.d/wlanclient
 etc/rc.d/rc0.d/K01grub-btrfsd
 #etc/rc.d/rc0.d/K01vdradmin
 etc/rc.d/rc0.d/K08fcron
+etc/rc.d/rc0.d/K10openvpn-rw
+etc/rc.d/rc0.d/K11openvpn-n2n
 etc/rc.d/rc0.d/K28apache
 etc/rc.d/rc0.d/K30sshd
 etc/rc.d/rc0.d/K47setclock
@@ -135,6 +137,8 @@ etc/rc.d/rc3.d/S24cyrus-sasl
 etc/rc.d/rc3.d/S30sshd
 etc/rc.d/rc3.d/S32apache
 etc/rc.d/rc3.d/S40fcron
+etc/rc.d/rc3.d/S51openvpn-n2n
+etc/rc.d/rc3.d/S50openvpn-rw
 etc/rc.d/rc3.d/S50wireguard
 etc/rc.d/rc3.d/S98rc.local
 etc/rc.d/rc3.d/S99grub-btrfsd
@@ -143,6 +147,8 @@ etc/rc.d/rc3.d/S99grub-btrfsd
 etc/rc.d/rc6.d/K01grub-btrfsd
 #etc/rc.d/rc6.d/K01vdradmin
 etc/rc.d/rc6.d/K08fcron
+etc/rc.d/rc6.d/K10openvpn-rw
+etc/rc.d/rc6.d/K11openvpn-n2n
 etc/rc.d/rc6.d/K28apache
 etc/rc.d/rc6.d/K30sshd
 etc/rc.d/rc6.d/K47setclock
diff --git a/config/rootfiles/common/riscv64/initscripts b/config/rootfiles/common/riscv64/initscripts
index 11cfaf2be8..6942072576 100644
--- a/config/rootfiles/common/riscv64/initscripts
+++ b/config/rootfiles/common/riscv64/initscripts
@@ -46,7 +46,6 @@ etc/rc.d/init.d/networking/orange
 etc/rc.d/init.d/networking/red
 #etc/rc.d/init.d/networking/red.down
 etc/rc.d/init.d/networking/red.down/10-ipsec
-etc/rc.d/init.d/networking/red.down/10-ovpn
 etc/rc.d/init.d/networking/red.down/10-static-routes
 etc/rc.d/init.d/networking/red.down/20-firewall
 etc/rc.d/init.d/networking/red.down/99-beep
@@ -62,7 +61,6 @@ etc/rc.d/init.d/networking/red.up/27-RS-squid
 etc/rc.d/init.d/networking/red.up/30-ddns
 #etc/rc.d/init.d/networking/red.up/35-guardian
 etc/rc.d/init.d/networking/red.up/50-ipsec
-etc/rc.d/init.d/networking/red.up/50-ovpn
 etc/rc.d/init.d/networking/red.up/60-collectd
 etc/rc.d/init.d/networking/red.up/98-leds
 etc/rc.d/init.d/networking/red.up/99-beep
@@ -70,6 +68,8 @@ etc/rc.d/init.d/networking/red.up/99-fireinfo
 etc/rc.d/init.d/networking/red.up/99-pakfire-update
 etc/rc.d/init.d/networking/wpa_supplicant.exe
 etc/rc.d/init.d/ntp
+etc/rc.d/init.d/openvpn-n2n
+etc/rc.d/init.d/openvpn-rw
 etc/rc.d/init.d/pakfire
 etc/rc.d/init.d/partresize
 etc/rc.d/init.d/rc
@@ -97,6 +97,8 @@ etc/rc.d/init.d/wlanclient
 etc/rc.d/rc0.d/K01grub-btrfsd
 #etc/rc.d/rc0.d/K01vdradmin
 etc/rc.d/rc0.d/K08fcron
+etc/rc.d/rc0.d/K10openvpn-rw
+etc/rc.d/rc0.d/K11openvpn-n2n
 etc/rc.d/rc0.d/K28apache
 etc/rc.d/rc0.d/K30sshd
 etc/rc.d/rc0.d/K47setclock
@@ -134,6 +136,8 @@ etc/rc.d/rc3.d/S24cyrus-sasl
 etc/rc.d/rc3.d/S30sshd
 etc/rc.d/rc3.d/S32apache
 etc/rc.d/rc3.d/S40fcron
+etc/rc.d/rc3.d/S51openvpn-n2n
+etc/rc.d/rc3.d/S50openvpn-rw
 etc/rc.d/rc3.d/S50wireguard
 etc/rc.d/rc3.d/S98rc.local
 etc/rc.d/rc3.d/S99grub-btrfsd
@@ -142,6 +146,8 @@ etc/rc.d/rc3.d/S99grub-btrfsd
 etc/rc.d/rc6.d/K01grub-btrfsd
 #etc/rc.d/rc6.d/K01vdradmin
 etc/rc.d/rc6.d/K08fcron
+etc/rc.d/rc6.d/K10openvpn-rw
+etc/rc.d/rc6.d/K11openvpn-n2n
 etc/rc.d/rc6.d/K28apache
 etc/rc.d/rc6.d/K30sshd
 etc/rc.d/rc6.d/K47setclock
diff --git a/config/rootfiles/common/x86_64/initscripts b/config/rootfiles/common/x86_64/initscripts
index 11cfaf2be8..6942072576 100644
--- a/config/rootfiles/common/x86_64/initscripts
+++ b/config/rootfiles/common/x86_64/initscripts
@@ -46,7 +46,6 @@ etc/rc.d/init.d/networking/orange
 etc/rc.d/init.d/networking/red
 #etc/rc.d/init.d/networking/red.down
 etc/rc.d/init.d/networking/red.down/10-ipsec
-etc/rc.d/init.d/networking/red.down/10-ovpn
 etc/rc.d/init.d/networking/red.down/10-static-routes
 etc/rc.d/init.d/networking/red.down/20-firewall
 etc/rc.d/init.d/networking/red.down/99-beep
@@ -62,7 +61,6 @@ etc/rc.d/init.d/networking/red.up/27-RS-squid
 etc/rc.d/init.d/networking/red.up/30-ddns
 #etc/rc.d/init.d/networking/red.up/35-guardian
 etc/rc.d/init.d/networking/red.up/50-ipsec
-etc/rc.d/init.d/networking/red.up/50-ovpn
 etc/rc.d/init.d/networking/red.up/60-collectd
 etc/rc.d/init.d/networking/red.up/98-leds
 etc/rc.d/init.d/networking/red.up/99-beep
@@ -70,6 +68,8 @@ etc/rc.d/init.d/networking/red.up/99-fireinfo
 etc/rc.d/init.d/networking/red.up/99-pakfire-update
 etc/rc.d/init.d/networking/wpa_supplicant.exe
 etc/rc.d/init.d/ntp
+etc/rc.d/init.d/openvpn-n2n
+etc/rc.d/init.d/openvpn-rw
 etc/rc.d/init.d/pakfire
 etc/rc.d/init.d/partresize
 etc/rc.d/init.d/rc
@@ -97,6 +97,8 @@ etc/rc.d/init.d/wlanclient
 etc/rc.d/rc0.d/K01grub-btrfsd
 #etc/rc.d/rc0.d/K01vdradmin
 etc/rc.d/rc0.d/K08fcron
+etc/rc.d/rc0.d/K10openvpn-rw
+etc/rc.d/rc0.d/K11openvpn-n2n
 etc/rc.d/rc0.d/K28apache
 etc/rc.d/rc0.d/K30sshd
 etc/rc.d/rc0.d/K47setclock
@@ -134,6 +136,8 @@ etc/rc.d/rc3.d/S24cyrus-sasl
 etc/rc.d/rc3.d/S30sshd
 etc/rc.d/rc3.d/S32apache
 etc/rc.d/rc3.d/S40fcron
+etc/rc.d/rc3.d/S51openvpn-n2n
+etc/rc.d/rc3.d/S50openvpn-rw
 etc/rc.d/rc3.d/S50wireguard
 etc/rc.d/rc3.d/S98rc.local
 etc/rc.d/rc3.d/S99grub-btrfsd
@@ -142,6 +146,8 @@ etc/rc.d/rc3.d/S99grub-btrfsd
 etc/rc.d/rc6.d/K01grub-btrfsd
 #etc/rc.d/rc6.d/K01vdradmin
 etc/rc.d/rc6.d/K08fcron
+etc/rc.d/rc6.d/K10openvpn-rw
+etc/rc.d/rc6.d/K11openvpn-n2n
 etc/rc.d/rc6.d/K28apache
 etc/rc.d/rc6.d/K30sshd
 etc/rc.d/rc6.d/K47setclock
diff --git a/config/rootfiles/core/197/filelists/files b/config/rootfiles/core/197/filelists/files
index 05a3215267..b197f3f2ae 100644
--- a/config/rootfiles/core/197/filelists/files
+++ b/config/rootfiles/core/197/filelists/files
@@ -1,4 +1,21 @@
 etc/httpd/conf/vhosts.d/ipfire-interface-ssl.conf
+etc/rc.d/init.d/firewall
+etc/rc.d/init.d/functions
+etc/rc.d/init.d/openvpn-n2n
+etc/rc.d/init.d/openvpn-rw
+etc/rc.d/rc0.d/K10openvpn-rw
+etc/rc.d/rc0.d/K11openvpn-n2n
+etc/rc.d/rc3.d/S50openvpn-rw
+etc/rc.d/rc3.d/S51openvpn-n2n
+etc/rc.d/rc6.d/K10openvpn-rw
+etc/rc.d/rc6.d/K11openvpn-n2n
+srv/web/ipfire/cgi-bin/ovpnmain.cgi
+srv/web/ipfire/cgi-bin/services.cgi
+srv/web/ipfire/cgi-bin/vulnerabilities.cgi
+srv/web/ipfire/html/themes/ipfire/include/css/style.css
+usr/local/bin/openvpnctrl
+var/ipfire/general-functions.pl
+var/ipfire/header.pl
 var/ipfire/langs/list
 var/ipfire/menu.d/20-status.menu
 var/ipfire/menu.d/40-services.menu
diff --git a/config/rootfiles/core/197/filelists/openvpn b/config/rootfiles/core/197/filelists/openvpn
new file mode 120000
index 0000000000..493f3f7a42
--- /dev/null
+++ b/config/rootfiles/core/197/filelists/openvpn
@@ -0,0 +1 @@
+../../../common/openvpn
\ No newline at end of file
diff --git a/config/rootfiles/core/197/update.sh b/config/rootfiles/core/197/update.sh
index 311bddb859..30d618b0e4 100644
--- a/config/rootfiles/core/197/update.sh
+++ b/config/rootfiles/core/197/update.sh
@@ -32,9 +32,13 @@ for (( i=1; i<=$core; i++ )); do
 done
 
 # Stop services
+/usr/local/bin/openvpnctrl -k
+/usr/local/bin/openvpnctrl -kn2n
 
 # Remove files
 rm -vf \
+	/etc/rc.d/init.d/networking/red.down/10-ovpn \
+	/etc/rc.d/init.d/networking/red.up/50-ovpn \
 	/usr/lib/libbtrfs.so.0.? \
 	/usr/lib/libbtrfsutil.so.1.?
 
@@ -53,6 +57,10 @@ ldconfig
 # Apply SSH configuration
 /usr/local/bin/sshctrl
 
+# Start services
+/etc/init.d/openvpn-n2n start
+/etc/init.d/openvpn-rw start
+
 # Reload Apache2
 /etc/init.d/apache reload
 
diff --git a/doc/language_issues.de b/doc/language_issues.de
index 069057d588..a98202e8d7 100644
--- a/doc/language_issues.de
+++ b/doc/language_issues.de
@@ -23,11 +23,11 @@ WARNING: translation string unused: Captive vout
 WARNING: translation string unused: ConnSched scheduler
 WARNING: translation string unused: ConnSched select profile
 WARNING: translation string unused: Daily
-WARNING: translation string unused: Disabled
 WARNING: translation string unused: Existing Files
 WARNING: translation string unused: HDD temperature
 WARNING: translation string unused: Level7 rule
 WARNING: translation string unused: Local VPN IP
+WARNING: translation string unused: OVPN
 WARNING: translation string unused: Pages
 WARNING: translation string unused: Ping
 WARNING: translation string unused: Queuelenght
@@ -129,6 +129,7 @@ WARNING: translation string unused: apply
 WARNING: translation string unused: archive not exist
 WARNING: translation string unused: artist
 WARNING: translation string unused: attemps
+WARNING: translation string unused: attention
 WARNING: translation string unused: avoid dod
 WARNING: translation string unused: backup config floppy
 WARNING: translation string unused: backup configuration
@@ -156,8 +157,12 @@ WARNING: translation string unused: cannot enable both nat traversal and compres
 WARNING: translation string unused: cant enable xtaccess
 WARNING: translation string unused: capsinactive
 WARNING: translation string unused: ccd err iroute
+WARNING: translation string unused: ccd err name
 WARNING: translation string unused: ccd err netadr
+WARNING: translation string unused: ccd hint
+WARNING: translation string unused: ccd iroutehint
 WARNING: translation string unused: ccd maxclients
+WARNING: translation string unused: ccd noaddnet
 WARNING: translation string unused: cfg restart
 WARNING: translation string unused: change share
 WARNING: translation string unused: check for net traffic update
@@ -183,6 +188,8 @@ WARNING: translation string unused: cpu frequency per
 WARNING: translation string unused: cpu usage per
 WARNING: translation string unused: create mask
 WARNING: translation string unused: create new backup
+WARNING: translation string unused: crypto error
+WARNING: translation string unused: crypto warning
 WARNING: translation string unused: current media
 WARNING: translation string unused: current ovpn
 WARNING: translation string unused: current playlist
@@ -215,11 +222,13 @@ WARNING: translation string unused: destination ip bad
 WARNING: translation string unused: destination ip or net
 WARNING: translation string unused: destination net
 WARNING: translation string unused: destination port overlaps
+WARNING: translation string unused: dh
 WARNING: translation string unused: dhcp base ip fixed lease
 WARNING: translation string unused: dhcp create fixed leases
 WARNING: translation string unused: dhcp fixed lease err1
 WARNING: translation string unused: dhcp fixed lease help1
 WARNING: translation string unused: dhcp mode
+WARNING: translation string unused: dhcp-options
 WARNING: translation string unused: dial user password
 WARNING: translation string unused: dial user password has been changed
 WARNING: translation string unused: dialup settings
@@ -231,6 +240,7 @@ WARNING: translation string unused: disk access
 WARNING: translation string unused: display charset
 WARNING: translation string unused: display traffic at home
 WARNING: translation string unused: display webinterface effects
+WARNING: translation string unused: dl client arch insecure
 WARNING: translation string unused: dmz pinhole configuration
 WARNING: translation string unused: dmz pinhole rule added
 WARNING: translation string unused: dmz pinhole rule removed
@@ -355,6 +365,7 @@ WARNING: translation string unused: fwhost Custom Host
 WARNING: translation string unused: fwhost Custom Network
 WARNING: translation string unused: fwhost IpSec Host
 WARNING: translation string unused: fwhost IpSec Network
+WARNING: translation string unused: fwhost OpenVPN N-2-N
 WARNING: translation string unused: fwhost OpenVPN static host
 WARNING: translation string unused: fwhost OpenVPN static network
 WARNING: translation string unused: fwhost Standard Network
@@ -430,6 +441,9 @@ WARNING: translation string unused: intrusion detection system2
 WARNING: translation string unused: invalid cache size
 WARNING: translation string unused: invalid date entered
 WARNING: translation string unused: invalid downlink speed
+WARNING: translation string unused: invalid input for keepalive 1
+WARNING: translation string unused: invalid input for keepalive 1:2
+WARNING: translation string unused: invalid input for keepalive 2
 WARNING: translation string unused: invalid input for oink code
 WARNING: translation string unused: invalid loaded file
 WARNING: translation string unused: invalid md5sum
@@ -448,6 +462,7 @@ WARNING: translation string unused: ipblocklist category invalid
 WARNING: translation string unused: ipblocklist category reputation
 WARNING: translation string unused: ipblocklist category scanner
 WARNING: translation string unused: ipfire side
+WARNING: translation string unused: ipfire side is invalid
 WARNING: translation string unused: ipsec no connections
 WARNING: translation string unused: iptable rules
 WARNING: translation string unused: javascript menu error1
@@ -466,6 +481,7 @@ WARNING: translation string unused: load printer
 WARNING: translation string unused: loaded modules
 WARNING: translation string unused: local hard disk
 WARNING: translation string unused: local master
+WARNING: translation string unused: local vpn hostname/ip
 WARNING: translation string unused: localkey
 WARNING: translation string unused: localkeyfile
 WARNING: translation string unused: locationblock country code
@@ -476,6 +492,7 @@ WARNING: translation string unused: log level
 WARNING: translation string unused: log var messages
 WARNING: translation string unused: log view
 WARNING: translation string unused: log viewer
+WARNING: translation string unused: log-options
 WARNING: translation string unused: logging
 WARNING: translation string unused: loosedirectorychecking
 WARNING: translation string unused: ls_dhcpd
@@ -511,6 +528,7 @@ WARNING: translation string unused: meaning
 WARNING: translation string unused: memory usage per
 WARNING: translation string unused: messages logging
 WARNING: translation string unused: min size
+WARNING: translation string unused: misc-options
 WARNING: translation string unused: missing dat
 WARNING: translation string unused: missing gz
 WARNING: translation string unused: modem on com1
@@ -594,10 +612,15 @@ WARNING: translation string unused: outgoing firewall reset
 WARNING: translation string unused: outgoing firewall view group
 WARNING: translation string unused: outgoing firewall warning
 WARNING: translation string unused: override mtu
+WARNING: translation string unused: ovpn add conf
 WARNING: translation string unused: ovpn config
+WARNING: translation string unused: ovpn crypt options
 WARNING: translation string unused: ovpn device
 WARNING: translation string unused: ovpn dl
 WARNING: translation string unused: ovpn engines
+WARNING: translation string unused: ovpn errmsg green already pushed
+WARNING: translation string unused: ovpn errmsg invalid ip or mask
+WARNING: translation string unused: ovpn error md5
 WARNING: translation string unused: ovpn generating the root and host certificates
 WARNING: translation string unused: ovpn log
 WARNING: translation string unused: ovpn mtu-disc
@@ -607,7 +630,13 @@ WARNING: translation string unused: ovpn mtu-disc no
 WARNING: translation string unused: ovpn mtu-disc off
 WARNING: translation string unused: ovpn mtu-disc with mssfix or fragment
 WARNING: translation string unused: ovpn mtu-disc yes
+WARNING: translation string unused: ovpn on blue
+WARNING: translation string unused: ovpn on orange
+WARNING: translation string unused: ovpn on red
 WARNING: translation string unused: ovpn reneg sec
+WARNING: translation string unused: ovpn routes push options
+WARNING: translation string unused: ovpn server status
+WARNING: translation string unused: ovpn warning rfc3280
 WARNING: translation string unused: ovpn_fastio
 WARNING: translation string unused: ovpn_fragment
 WARNING: translation string unused: ovpn_mssfix
@@ -678,6 +707,7 @@ WARNING: translation string unused: reset shares
 WARNING: translation string unused: resetglobals
 WARNING: translation string unused: resetpolicy
 WARNING: translation string unused: resetshares
+WARNING: translation string unused: restart ovpn server
 WARNING: translation string unused: restore hardware settings
 WARNING: translation string unused: restore settings
 WARNING: translation string unused: root
@@ -701,6 +731,7 @@ WARNING: translation string unused: selecttraffic
 WARNING: translation string unused: send email notification
 WARNING: translation string unused: send test mail
 WARNING: translation string unused: server reserved
+WARNING: translation string unused: server restart
 WARNING: translation string unused: server string
 WARNING: translation string unused: service added
 WARNING: translation string unused: service removed
@@ -709,6 +740,7 @@ WARNING: translation string unused: servicename
 WARNING: translation string unused: services settings
 WARNING: translation string unused: set
 WARNING: translation string unused: shaping list options
+WARNING: translation string unused: show dh
 WARNING: translation string unused: show last x lines
 WARNING: translation string unused: show share options
 WARNING: translation string unused: shuffle
@@ -749,6 +781,8 @@ WARNING: translation string unused: ssport forwarding
 WARNING: translation string unused: ssproxy graphs
 WARNING: translation string unused: sssystem status
 WARNING: translation string unused: sstraffic graphs
+WARNING: translation string unused: start ovpn server
+WARNING: translation string unused: stop ovpn server
 WARNING: translation string unused: subject test
 WARNING: translation string unused: subject warn
 WARNING: translation string unused: subnet
@@ -783,6 +817,7 @@ WARNING: translation string unused: tor 0 = disabled
 WARNING: translation string unused: tor accounting period daily
 WARNING: translation string unused: tor accounting period monthly
 WARNING: translation string unused: tor accounting period weekly
+WARNING: translation string unused: tor daemon
 WARNING: translation string unused: tor exit country
 WARNING: translation string unused: tor guard country
 WARNING: translation string unused: traffic back
@@ -921,6 +956,11 @@ WARNING: translation string unused: zoneconf val vlan amount assignment error
 WARNING: translation string unused: zoneconf val vlan tag assignment error
 WARNING: translation string unused: zoneconf val vlan tag range error
 WARNING: translation string unused: zoneconf val zoneslave amount error
+WARNING: untranslated string: AES-128-CBC = AES - CBC Mode - 128 Bit
+WARNING: untranslated string: AES-128-GCM = AES - GCM Mode - 128 Bit
+WARNING: untranslated string: AES-256-CBC = AES - CBC Mode - 256 Bit
+WARNING: untranslated string: AES-256-GCM = AES - GCM Mode - 256 Bit
+WARNING: untranslated string: CHACHA20-POLY1305 = ChaCha20-Poly1305
 WARNING: untranslated string: access point name = Access Point Name
 WARNING: untranslated string: access point name is invalid = Access Point Name is invalid
 WARNING: untranslated string: access point name is required = Access Point Name is required
@@ -1000,7 +1040,23 @@ WARNING: untranslated string: netbios nameserver daemon = NetBIOS Nameserver Dae
 WARNING: untranslated string: no entries = No entries at the moment.
 WARNING: untranslated string: oops something went wrong = Oops, something went wrong...
 WARNING: untranslated string: optional = Optional
+WARNING: untranslated string: ovpn ciphers = Ciphers
+WARNING: untranslated string: ovpn crypto settings = Cryptographic Settings
+WARNING: untranslated string: ovpn dhcp settings = DHCP Settings
+WARNING: untranslated string: ovpn dynamic client subnet = Dynamic Client Subnet
+WARNING: untranslated string: ovpn errmsg invalid route = Invalid route
+WARNING: untranslated string: ovpn fallback cipher = Fallback Cipher
+WARNING: untranslated string: ovpn fallback cipher help = This cipher is being used by clients that do not support cipher negotiation.
+WARNING: untranslated string: ovpn fqdn = FQDN
+WARNING: untranslated string: ovpn misc settings = Miscellaneous Settings
+WARNING: untranslated string: ovpn no cipher selected = No cipher selected
+WARNING: untranslated string: ovpn protocol settings = Protocol Settings
+WARNING: untranslated string: ovpn push default route = Push Default Route
 WARNING: untranslated string: ovpn roadwarrior server = OpenVPN Roadwarrior Server
+WARNING: untranslated string: ovpn roadwarrior settings = Roadwarrior Settings
+WARNING: untranslated string: ovpn routing settings = Routing Settings
+WARNING: untranslated string: ovpn transport protocol = Transport Protocol
+WARNING: untranslated string: ovpn unsupported cipher selected = Unknown cipher selected
 WARNING: untranslated string: pakfire invalid tree = Invalid repository selected
 WARNING: untranslated string: quality of service = Quality of Service
 WARNING: untranslated string: reg_file_data_sampling = Register File Data Sampling (RFDS)
@@ -1013,6 +1069,8 @@ WARNING: untranslated string: route config changed = unknown string
 WARNING: untranslated string: routing = Routing
 WARNING: untranslated string: routing config added = unknown string
 WARNING: untranslated string: routing config changed = unknown string
+WARNING: untranslated string: rss = RSS
+WARNING: untranslated string: rss long = Resident Set Size
 WARNING: untranslated string: samba server role member = Domain Member
 WARNING: untranslated string: samba server role standalone = Standalone
 WARNING: untranslated string: show tls-auth key = Show tls-auth key
diff --git a/doc/language_issues.en b/doc/language_issues.en
index 4827a5eb39..c40eaf2620 100644
--- a/doc/language_issues.en
+++ b/doc/language_issues.en
@@ -1,9 +1,14 @@
 WARNING: untranslated string: 24 hours = 24 Hours
+WARNING: untranslated string: AES-128-CBC = AES - CBC Mode - 128 Bit
+WARNING: untranslated string: AES-128-GCM = AES - GCM Mode - 128 Bit
+WARNING: untranslated string: AES-256-CBC = AES - CBC Mode - 256 Bit
+WARNING: untranslated string: AES-256-GCM = AES - GCM Mode - 256 Bit
 WARNING: untranslated string: Act as = Act as:
 WARNING: untranslated string: Add Level7 rule = Add Level7 rule
 WARNING: untranslated string: Add Port Rule = Add port rule
 WARNING: untranslated string: Add Rule = Add rule
 WARNING: untranslated string: Add a route = Add a route
+WARNING: untranslated string: CHACHA20-POLY1305 = ChaCha20-Poly1305
 WARNING: untranslated string: Captive = Captive Portal
 WARNING: untranslated string: Captive ACTIVATE = unknown string
 WARNING: untranslated string: Captive GAIN ACCESS = GAIN ACCESS
@@ -57,6 +62,7 @@ WARNING: untranslated string: ConnSched shutdown = Shutdown
 WARNING: untranslated string: ConnSched time = Time:
 WARNING: untranslated string: ConnSched up = Up
 WARNING: untranslated string: ConnSched weekdays = Days of the week:
+WARNING: untranslated string: Disabled = Disabled
 WARNING: untranslated string: Edit an existing route = Edit an existing route
 WARNING: untranslated string: Enter TOS = Activate or deactivate TOS-bits <br /> and then press <i>Save</i>.
 WARNING: untranslated string: Level7 Protocol = Level7-Protocol
@@ -68,7 +74,6 @@ WARNING: untranslated string: MTU settings = MTU settings:
 WARNING: untranslated string: Number of Countries for the pie chart = Number of Countries for the pie chart
 WARNING: untranslated string: Number of IPs for the pie chart = Number of IPs for the pie chart
 WARNING: untranslated string: Number of Ports for the pie chart = Number of ports for the pie chart
-WARNING: untranslated string: OVPN = OpenVPN
 WARNING: untranslated string: OpenVPN = OpenVPN
 WARNING: untranslated string: Port Rule = Port-Rule
 WARNING: untranslated string: QoS not enabled = QoS is not enabled!
@@ -100,7 +105,7 @@ WARNING: untranslated string: addons = Add-Ons
 WARNING: untranslated string: administrator password = Administrator password
 WARNING: untranslated string: administrator username = Administrator username
 WARNING: untranslated string: advanced = Advanced
-WARNING: untranslated string: advanced server = Advanced server options
+WARNING: untranslated string: advanced server = Advanced Settings
 WARNING: untranslated string: advproxy AUTH always required = Require authentication for unrestricted source addresses
 WARNING: untranslated string: advproxy AUTH auth cache TTL = Authentication cache TTL (in minutes)
 WARNING: untranslated string: advproxy AUTH global settings = Global authentication settings
@@ -320,7 +325,6 @@ WARNING: untranslated string: arp table entries = ARP Table Entries
 WARNING: untranslated string: asn lookup failed = AS lookup failed
 WARNING: untranslated string: atm device = Device:
 WARNING: untranslated string: atm settings = ATM settings
-WARNING: untranslated string: attention = ATTENTION
 WARNING: untranslated string: august = August
 WARNING: untranslated string: authentication = Authentication:
 WARNING: untranslated string: automatic = Automatic
@@ -439,22 +443,18 @@ WARNING: untranslated string: ccd err isipsecrw = The given subnet address is al
 WARNING: untranslated string: ccd err isovpnn2n = The subnet address is already in use for an OpenVPN net-to-net connection.
 WARNING: untranslated string: ccd err isovpnnet = The subnet address is already in use for the OpenVPN server.
 WARNING: untranslated string: ccd err issubnet = Subnet address already in use.
-WARNING: untranslated string: ccd err name = Please choose a name.
 WARNING: untranslated string: ccd err nameexist = Name already exists.
 WARNING: untranslated string: ccd err netadrexist = Network already exists.
 WARNING: untranslated string: ccd err orange = This is the ORANGE subnet.
 WARNING: untranslated string: ccd err red = This is the RED subnet.
 WARNING: untranslated string: ccd err routeovpn = Already used by OpenVPN server.
 WARNING: untranslated string: ccd err routeovpn2 = Already pushed from OpenVPN server.
-WARNING: untranslated string: ccd hint = On this page you are able to define static networks from which the roadwarrior clients can get fixed IP address assignments.
 WARNING: untranslated string: ccd invalid = Invalid.
 WARNING: untranslated string: ccd iroute = IPFire has access to these networks on the client's site
 WARNING: untranslated string: ccd iroute2 = Client has access to these networks on IPFire's site
-WARNING: untranslated string: ccd iroutehint = Attention! If you change these settings, you have to restart the OpenVPN server that the changes take effect!
 WARNING: untranslated string: ccd modify = Change network
 WARNING: untranslated string: ccd name = Name
 WARNING: untranslated string: ccd net = Static IP address pools
-WARNING: untranslated string: ccd noaddnet = You can only add new static networks when OpenVPN server is stopped.
 WARNING: untranslated string: ccd none = None
 WARNING: untranslated string: ccd routes = Routing:
 WARNING: untranslated string: ccd subnet = Subnet
@@ -519,8 +519,6 @@ WARNING: untranslated string: create = Create
 WARNING: untranslated string: credits = Credits
 WARNING: untranslated string: crl = Certificate Revocation List
 WARNING: untranslated string: cron server = CRON Server
-WARNING: untranslated string: crypto error = Cryptographic error
-WARNING: untranslated string: crypto warning = Cryptographic warning
 WARNING: untranslated string: current = Current
 WARNING: untranslated string: current aliases = Current aliases
 WARNING: untranslated string: current class = Current class
@@ -555,13 +553,12 @@ WARNING: untranslated string: desired = Desired
 WARNING: untranslated string: dest ip and port = Dest. IP: Port
 WARNING: untranslated string: destination = Destination
 WARNING: untranslated string: destination ip = Destination IP
-WARNING: untranslated string: destination port = Destination port
+WARNING: untranslated string: destination port = Destination Port
 WARNING: untranslated string: destination port numbers = Destination port must be a valid port number or port range.
 WARNING: untranslated string: detail level = Detail level
 WARNING: untranslated string: details = Details
 WARNING: untranslated string: device = Device
 WARNING: untranslated string: devices on blue = Devices on BLUE
-WARNING: untranslated string: dh = Diffie-Hellman-Parameter
 WARNING: untranslated string: dhcp advopt add = Add a DHCP option
 WARNING: untranslated string: dhcp advopt added = DHCP option added
 WARNING: untranslated string: dhcp advopt blank value = DHCP Option value cannot be empty.
@@ -594,7 +591,6 @@ WARNING: untranslated string: dhcp server = DHCP Server
 WARNING: untranslated string: dhcp server disabled = DHCP server disabled.  Stopped.
 WARNING: untranslated string: dhcp server enabled = DHCP server enabled.  Restarting.
 WARNING: untranslated string: dhcp valid range required when deny known clients checked = Valid range required when "Deny known clients:" is checked
-WARNING: untranslated string: dhcp-options = DHCP push options
 WARNING: untranslated string: dial = Connect
 WARNING: untranslated string: dial profile = Connect with profile
 WARNING: untranslated string: dialing mode = Dialing mode:
@@ -605,8 +601,7 @@ WARNING: untranslated string: disconnected = Disconnected
 WARNING: untranslated string: disk usage = Disk usage
 WARNING: untranslated string: display = Display
 WARNING: untranslated string: display hostname in window title = Display hostname in window title
-WARNING: untranslated string: dl client arch = Download Encrypted Client Package (zip)
-WARNING: untranslated string: dl client arch insecure = Download insecure Client Package (zip)
+WARNING: untranslated string: dl client arch = Download Client Configuration
 WARNING: untranslated string: dmz = DMZ
 WARNING: untranslated string: dnat address = Firewall Interface
 WARNING: untranslated string: dns check failed = DNS check failed
@@ -898,7 +893,6 @@ WARNING: untranslated string: fwdfw wd_sun = Sun
 WARNING: untranslated string: fwdfw wd_thu = Thu
 WARNING: untranslated string: fwdfw wd_tue = Tue
 WARNING: untranslated string: fwdfw wd_wed = Wed
-WARNING: untranslated string: fwhost OpenVPN N-2-N = OpenVPN Net-to-Net
 WARNING: untranslated string: fwhost addgrp = Add new network/host group
 WARNING: untranslated string: fwhost addgrpname = Group name:
 WARNING: untranslated string: fwhost addhost = Add new host
@@ -1129,9 +1123,6 @@ WARNING: untranslated string: invalid input for inactivity timeout = Invalid inp
 WARNING: untranslated string: invalid input for interface address = Invalid input for interface address
 WARNING: untranslated string: invalid input for interface mode = Invalid input for interface mode
 WARNING: untranslated string: invalid input for interface mtu = Invalid input to interface MTU
-WARNING: untranslated string: invalid input for keepalive 1 = Invalid input for Keepalive ping
-WARNING: untranslated string: invalid input for keepalive 1:2 = Invalid input for Keepalive use at least a ratio of 1:2
-WARNING: untranslated string: invalid input for keepalive 2 = Invalid input for Keepalive ping-restart
 WARNING: untranslated string: invalid input for local ip address = Invalid input for local IP address
 WARNING: untranslated string: invalid input for max clients = Invalid input for Max Clients. The maximum of 1024 clients has been exceeded
 WARNING: untranslated string: invalid input for mode = Invalid input for mode
@@ -1194,7 +1185,6 @@ WARNING: untranslated string: ipblocklist output = Packets dropped (OUT)
 WARNING: untranslated string: ipblocklist use ipblocklists = Enable IP Blocklists
 WARNING: untranslated string: ipfire has now rebooted = IPFire is rebooting now.
 WARNING: untranslated string: ipfire has now shutdown = IPFire is shutting down now.
-WARNING: untranslated string: ipfire side is invalid = IPFire side is invalid.
 WARNING: untranslated string: ipfires hostname = IPFire's Hostname
 WARNING: untranslated string: ipinfo = IP info
 WARNING: untranslated string: ips throughput = Throughput
@@ -1237,7 +1227,6 @@ WARNING: untranslated string: local port = Local Port
 WARNING: untranslated string: local subnet = Local subnet:
 WARNING: untranslated string: local subnet is invalid = Local subnet is invalid.
 WARNING: untranslated string: local subnets = Local Subnets
-WARNING: untranslated string: local vpn hostname/ip = Local VPN Hostname/IP
 WARNING: untranslated string: location = Location
 WARNING: untranslated string: locationblock = Location Block
 WARNING: untranslated string: locationblock block countries = Block countries
@@ -1256,7 +1245,6 @@ WARNING: untranslated string: log settings = Log Settings
 WARNING: untranslated string: log summaries = Log summaries
 WARNING: untranslated string: log summary = Log Summary
 WARNING: untranslated string: log viewing options = Log viewing options
-WARNING: untranslated string: log-options = Logfile options
 WARNING: untranslated string: loged in at = Logged in at
 WARNING: untranslated string: logging server = Logging Server
 WARNING: untranslated string: loginlogout = Login/Logout
@@ -1321,7 +1309,6 @@ WARNING: untranslated string: minimal = Minimal
 WARNING: untranslated string: minimum = Minimum
 WARNING: untranslated string: minute = Minute
 WARNING: untranslated string: minutes = Minutes
-WARNING: untranslated string: misc-options = Miscellaneous options
 WARNING: untranslated string: mitigated = Mitigated
 WARNING: untranslated string: mmio stale data = MMIO Stale Data
 WARNING: untranslated string: mode = Mode
@@ -1445,30 +1432,35 @@ WARNING: untranslated string: outgoing firewall access = Outgoing Firewall Acces
 WARNING: untranslated string: outgoing overhead in bytes per second = Outgoing Overhead
 WARNING: untranslated string: outgoing traffic in bytes per second = Outgoing Traffic
 WARNING: untranslated string: ovpn = OpenVPN
-WARNING: untranslated string: ovpn add conf = Additional configuration
+WARNING: untranslated string: ovpn ciphers = Ciphers
 WARNING: untranslated string: ovpn con stat = OpenVPN Connection Statistics
 WARNING: untranslated string: ovpn connection name = Connection Name
-WARNING: untranslated string: ovpn crypt options = Cryptographic options
-WARNING: untranslated string: ovpn errmsg green already pushed = Route for green network is always set
-WARNING: untranslated string: ovpn errmsg invalid ip or mask = Invalid network-address or subnetmask
-WARNING: untranslated string: ovpn error md5 = You host certificate uses MD5 for the signature which is not accepted anymore. <br>Please update to the latest IPFire version and generate a new root and host certificate.</br><br>All OpenVPN clients needs then to be renewed!</br>
+WARNING: untranslated string: ovpn crypto settings = Cryptographic Settings
+WARNING: untranslated string: ovpn dhcp settings = DHCP Settings
+WARNING: untranslated string: ovpn dynamic client subnet = Dynamic Client Subnet
+WARNING: untranslated string: ovpn errmsg invalid route = Invalid route
+WARNING: untranslated string: ovpn fallback cipher = Fallback Cipher
+WARNING: untranslated string: ovpn fallback cipher help = This cipher is being used by clients that do not support cipher negotiation.
+WARNING: untranslated string: ovpn fqdn = FQDN
 WARNING: untranslated string: ovpn ha = Hash algorithm
 WARNING: untranslated string: ovpn mgmt in root range = A port number of 1024 or higher is required.
+WARNING: untranslated string: ovpn misc settings = Miscellaneous Settings
+WARNING: untranslated string: ovpn no cipher selected = No cipher selected
 WARNING: untranslated string: ovpn no connections = No active OpenVPN connections
-WARNING: untranslated string: ovpn on blue = OpenVPN on BLUE:
-WARNING: untranslated string: ovpn on orange = OpenVPN on ORANGE:
-WARNING: untranslated string: ovpn on red = OpenVPN on RED:
 WARNING: untranslated string: ovpn port in root range = A port number of 1024 or higher is required.
+WARNING: untranslated string: ovpn protocol settings = Protocol Settings
+WARNING: untranslated string: ovpn push default route = Push Default Route
 WARNING: untranslated string: ovpn roadwarrior server = OpenVPN Roadwarrior Server
-WARNING: untranslated string: ovpn routes push = Routes (one per line) e.g. 192.168.10.0/255.255.255.0 192.168.20.0/24
-WARNING: untranslated string: ovpn routes push options = Route push options
+WARNING: untranslated string: ovpn roadwarrior settings = Roadwarrior Settings
+WARNING: untranslated string: ovpn routes push = Custom Routes
+WARNING: untranslated string: ovpn routing settings = Routing Settings
 WARNING: untranslated string: ovpn rw connection log = OpenVPN Roadwarrior Connections Log
-WARNING: untranslated string: ovpn server status = Current OpenVPN server status:
 WARNING: untranslated string: ovpn subnet = OpenVPN subnet:
 WARNING: untranslated string: ovpn subnet is invalid = OpenVPN subnet is invalid.
 WARNING: untranslated string: ovpn subnet overlap = OpenVPN Subnet overlaps with : 
 WARNING: untranslated string: ovpn tls auth = TLS Channel Protection:
-WARNING: untranslated string: ovpn warning rfc3280 = Your host certificate is not RFC3280 compliant. <br>Please update to the latest IPFire version and generate as soon as possible a new root and host certificate.</br><br>All OpenVPN clients needs then to be renewed!</br>
+WARNING: untranslated string: ovpn transport protocol = Transport Protocol
+WARNING: untranslated string: ovpn unsupported cipher selected = Unknown cipher selected
 WARNING: untranslated string: pagerefresh = Page is beeing refreshed, please wait.
 WARNING: untranslated string: pak update = Update
 WARNING: untranslated string: pakfire ago = ago.
@@ -1612,7 +1604,6 @@ WARNING: untranslated string: required field = Required field
 WARNING: untranslated string: reset = Reset
 WARNING: untranslated string: resetting the vpn configuration will remove the root ca, the host certificate and all certificate based connections = Resetting the X509 remove the root CA, the host certificate and all certificate based connections.
 WARNING: untranslated string: restart = Restart
-WARNING: untranslated string: restart ovpn server = Restart OpenVPN server
 WARNING: untranslated string: restore = Restore
 WARNING: untranslated string: restore defaults = Restore defaults
 WARNING: untranslated string: retbleed = Retbleed
@@ -1624,6 +1615,8 @@ WARNING: untranslated string: routing config added = unknown string
 WARNING: untranslated string: routing config changed = unknown string
 WARNING: untranslated string: routing table = unknown string
 WARNING: untranslated string: routing table entries = Routing Table Entries
+WARNING: untranslated string: rss = RSS
+WARNING: untranslated string: rss long = Resident Set Size
 WARNING: untranslated string: running = RUNNING
 WARNING: untranslated string: samba = Samba
 WARNING: untranslated string: samba join a domain = Join a domain
@@ -1632,7 +1625,7 @@ WARNING: untranslated string: samba server role member = Domain Member
 WARNING: untranslated string: samba server role standalone = Standalone
 WARNING: untranslated string: saturday = Saturday
 WARNING: untranslated string: save = Save
-WARNING: untranslated string: save-adv-options = Save advanced options
+WARNING: untranslated string: save-adv-options = Save Advanced Settings
 WARNING: untranslated string: scanned = Scanned
 WARNING: untranslated string: script name = Script name:
 WARNING: untranslated string: search = Search
@@ -1649,7 +1642,6 @@ WARNING: untranslated string: send cr = ISP requires Carriage Return:
 WARNING: untranslated string: sent = Sent
 WARNING: untranslated string: september = September
 WARNING: untranslated string: serial = Serial
-WARNING: untranslated string: server restart = You are not able to save any changes while the OpenVPN server is running.
 WARNING: untranslated string: service = Service
 WARNING: untranslated string: service boot setting unavailable = No valid runlevel symlink was found for the initscript of this service.
 WARNING: untranslated string: service name = Service name:
@@ -1664,7 +1656,6 @@ WARNING: untranslated string: show ajax speedmeter in footer = Show Ajax speedme
 WARNING: untranslated string: show ca certificate = Show CA certificate
 WARNING: untranslated string: show certificate = Show file
 WARNING: untranslated string: show crl = Show certificate revocation list
-WARNING: untranslated string: show dh = Show Diffie-Hellman parameters
 WARNING: untranslated string: show host certificate = Show host certificate
 WARNING: untranslated string: show otp qrcode = Show OTP QRCode
 WARNING: untranslated string: show root certificate = Show root certificate
@@ -1725,7 +1716,6 @@ WARNING: untranslated string: standard = Standard
 WARNING: untranslated string: standard login script = Standard login script
 WARNING: untranslated string: start = Start
 WARNING: untranslated string: start address = Start address:
-WARNING: untranslated string: start ovpn server = Start OpenVPN Server
 WARNING: untranslated string: state or province = State or Province
 WARNING: untranslated string: static ip = Static IP
 WARNING: untranslated string: static routes = Static Routes
@@ -1734,7 +1724,6 @@ WARNING: untranslated string: status information = Status information
 WARNING: untranslated string: status ovpn = OpenVPN
 WARNING: untranslated string: std classes = Standardclasses
 WARNING: untranslated string: stop = Stop
-WARNING: untranslated string: stop ovpn server = Stop OpenVPN Server
 WARNING: untranslated string: stopped = STOPPED
 WARNING: untranslated string: strict = Strict
 WARNING: untranslated string: subject = Subject
@@ -1787,7 +1776,6 @@ WARNING: untranslated string: tor common settings = Common Settings
 WARNING: untranslated string: tor configuration = Tor Configuration
 WARNING: untranslated string: tor connected relays = Connected relays
 WARNING: untranslated string: tor contact info = Contact Info
-WARNING: untranslated string: tor daemon = Daemon
 WARNING: untranslated string: tor directory port = Directory port
 WARNING: untranslated string: tor enabled = Enable Tor
 WARNING: untranslated string: tor errmsg invalid accounting limit = Invalid accounting limit
diff --git a/doc/language_issues.es b/doc/language_issues.es
index ae2f7f3a67..30f9e8407a 100644
--- a/doc/language_issues.es
+++ b/doc/language_issues.es
@@ -24,11 +24,11 @@ WARNING: translation string unused: Captive vout
 WARNING: translation string unused: ConnSched scheduler
 WARNING: translation string unused: ConnSched select profile
 WARNING: translation string unused: Daily
-WARNING: translation string unused: Disabled
 WARNING: translation string unused: Existing Files
 WARNING: translation string unused: HDD temperature
 WARNING: translation string unused: Level7 rule
 WARNING: translation string unused: Local VPN IP
+WARNING: translation string unused: OVPN
 WARNING: translation string unused: Pages
 WARNING: translation string unused: Ping
 WARNING: translation string unused: Queuelenght
@@ -132,6 +132,7 @@ WARNING: translation string unused: apply
 WARNING: translation string unused: archive not exist
 WARNING: translation string unused: artist
 WARNING: translation string unused: attemps
+WARNING: translation string unused: attention
 WARNING: translation string unused: avoid dod
 WARNING: translation string unused: backup archive
 WARNING: translation string unused: backup clear archive
@@ -176,7 +177,11 @@ WARNING: translation string unused: cannot enable both nat traversal and compres
 WARNING: translation string unused: cant enable xtaccess
 WARNING: translation string unused: capsinactive
 WARNING: translation string unused: ccd err iroute
+WARNING: translation string unused: ccd err name
 WARNING: translation string unused: ccd err netadr
+WARNING: translation string unused: ccd hint
+WARNING: translation string unused: ccd iroutehint
+WARNING: translation string unused: ccd noaddnet
 WARNING: translation string unused: cfg restart
 WARNING: translation string unused: change share
 WARNING: translation string unused: check for net traffic update
@@ -204,6 +209,8 @@ WARNING: translation string unused: cpu frequency per
 WARNING: translation string unused: cpu usage per
 WARNING: translation string unused: create mask
 WARNING: translation string unused: create new backup
+WARNING: translation string unused: crypto error
+WARNING: translation string unused: crypto warning
 WARNING: translation string unused: cryptographic settings
 WARNING: translation string unused: current media
 WARNING: translation string unused: current ovpn
@@ -237,6 +244,7 @@ WARNING: translation string unused: destination ip bad
 WARNING: translation string unused: destination ip or net
 WARNING: translation string unused: destination net
 WARNING: translation string unused: destination port overlaps
+WARNING: translation string unused: dh
 WARNING: translation string unused: dhcp base ip fixed lease
 WARNING: translation string unused: dhcp create fixed leases
 WARNING: translation string unused: dhcp fixed lease err1
@@ -244,6 +252,7 @@ WARNING: translation string unused: dhcp fixed lease help1
 WARNING: translation string unused: dhcp mode
 WARNING: translation string unused: dhcp server disabled on blue interface
 WARNING: translation string unused: dhcp server enabled on blue interface
+WARNING: translation string unused: dhcp-options
 WARNING: translation string unused: dial user password
 WARNING: translation string unused: dial user password has been changed
 WARNING: translation string unused: dialup settings
@@ -255,6 +264,7 @@ WARNING: translation string unused: disk access
 WARNING: translation string unused: display charset
 WARNING: translation string unused: display traffic at home
 WARNING: translation string unused: display webinterface effects
+WARNING: translation string unused: dl client arch insecure
 WARNING: translation string unused: dmz pinhole configuration
 WARNING: translation string unused: dmz pinhole rule added
 WARNING: translation string unused: dmz pinhole rule removed
@@ -382,6 +392,7 @@ WARNING: translation string unused: fwhost Custom Host
 WARNING: translation string unused: fwhost Custom Network
 WARNING: translation string unused: fwhost IpSec Host
 WARNING: translation string unused: fwhost IpSec Network
+WARNING: translation string unused: fwhost OpenVPN N-2-N
 WARNING: translation string unused: fwhost OpenVPN static host
 WARNING: translation string unused: fwhost OpenVPN static network
 WARNING: translation string unused: fwhost Standard Network
@@ -460,6 +471,9 @@ WARNING: translation string unused: intrusion detection system2
 WARNING: translation string unused: invalid cache size
 WARNING: translation string unused: invalid date entered
 WARNING: translation string unused: invalid downlink speed
+WARNING: translation string unused: invalid input for keepalive 1
+WARNING: translation string unused: invalid input for keepalive 1:2
+WARNING: translation string unused: invalid input for keepalive 2
 WARNING: translation string unused: invalid loaded file
 WARNING: translation string unused: invalid md5sum
 WARNING: translation string unused: invalid port list
@@ -477,6 +491,7 @@ WARNING: translation string unused: ipblocklist category invalid
 WARNING: translation string unused: ipblocklist category reputation
 WARNING: translation string unused: ipblocklist category scanner
 WARNING: translation string unused: ipfire side
+WARNING: translation string unused: ipfire side is invalid
 WARNING: translation string unused: ipsec no connections
 WARNING: translation string unused: iptable rules
 WARNING: translation string unused: javascript menu error1
@@ -495,6 +510,7 @@ WARNING: translation string unused: load printer
 WARNING: translation string unused: loaded modules
 WARNING: translation string unused: local hard disk
 WARNING: translation string unused: local master
+WARNING: translation string unused: local vpn hostname/ip
 WARNING: translation string unused: localkey
 WARNING: translation string unused: localkeyfile
 WARNING: translation string unused: locationblock country code
@@ -505,6 +521,7 @@ WARNING: translation string unused: log level
 WARNING: translation string unused: log var messages
 WARNING: translation string unused: log view
 WARNING: translation string unused: log viewer
+WARNING: translation string unused: log-options
 WARNING: translation string unused: logging
 WARNING: translation string unused: loosedirectorychecking
 WARNING: translation string unused: ls_dhcpd
@@ -540,6 +557,7 @@ WARNING: translation string unused: meaning
 WARNING: translation string unused: memory usage per
 WARNING: translation string unused: messages logging
 WARNING: translation string unused: min size
+WARNING: translation string unused: misc-options
 WARNING: translation string unused: missing dat
 WARNING: translation string unused: missing gz
 WARNING: translation string unused: modem on com1
@@ -625,10 +643,15 @@ WARNING: translation string unused: outgoing firewall reset
 WARNING: translation string unused: outgoing firewall view group
 WARNING: translation string unused: outgoing firewall warning
 WARNING: translation string unused: override mtu
+WARNING: translation string unused: ovpn add conf
 WARNING: translation string unused: ovpn config
+WARNING: translation string unused: ovpn crypt options
 WARNING: translation string unused: ovpn device
 WARNING: translation string unused: ovpn dl
 WARNING: translation string unused: ovpn engines
+WARNING: translation string unused: ovpn errmsg green already pushed
+WARNING: translation string unused: ovpn errmsg invalid ip or mask
+WARNING: translation string unused: ovpn error md5
 WARNING: translation string unused: ovpn generating the root and host certificates
 WARNING: translation string unused: ovpn log
 WARNING: translation string unused: ovpn mtu-disc
@@ -638,7 +661,13 @@ WARNING: translation string unused: ovpn mtu-disc no
 WARNING: translation string unused: ovpn mtu-disc off
 WARNING: translation string unused: ovpn mtu-disc with mssfix or fragment
 WARNING: translation string unused: ovpn mtu-disc yes
+WARNING: translation string unused: ovpn on blue
+WARNING: translation string unused: ovpn on orange
+WARNING: translation string unused: ovpn on red
 WARNING: translation string unused: ovpn reneg sec
+WARNING: translation string unused: ovpn routes push options
+WARNING: translation string unused: ovpn server status
+WARNING: translation string unused: ovpn warning rfc3280
 WARNING: translation string unused: ovpn_fastio
 WARNING: translation string unused: ovpn_mssfix
 WARNING: translation string unused: ovpn_mtudisc
@@ -718,6 +747,7 @@ WARNING: translation string unused: reset shares
 WARNING: translation string unused: resetglobals
 WARNING: translation string unused: resetpolicy
 WARNING: translation string unused: resetshares
+WARNING: translation string unused: restart ovpn server
 WARNING: translation string unused: restore hardware settings
 WARNING: translation string unused: restore settings
 WARNING: translation string unused: root
@@ -741,6 +771,7 @@ WARNING: translation string unused: selecttraffic
 WARNING: translation string unused: send email notification
 WARNING: translation string unused: send test mail
 WARNING: translation string unused: server reserved
+WARNING: translation string unused: server restart
 WARNING: translation string unused: server string
 WARNING: translation string unused: service added
 WARNING: translation string unused: service removed
@@ -751,6 +782,7 @@ WARNING: translation string unused: set
 WARNING: translation string unused: shaping add options
 WARNING: translation string unused: shaping list options
 WARNING: translation string unused: show areas
+WARNING: translation string unused: show dh
 WARNING: translation string unused: show last x lines
 WARNING: translation string unused: show lines
 WARNING: translation string unused: show share options
@@ -792,6 +824,8 @@ WARNING: translation string unused: ssport forwarding
 WARNING: translation string unused: ssproxy graphs
 WARNING: translation string unused: sssystem status
 WARNING: translation string unused: sstraffic graphs
+WARNING: translation string unused: start ovpn server
+WARNING: translation string unused: stop ovpn server
 WARNING: translation string unused: subject test
 WARNING: translation string unused: subject warn
 WARNING: translation string unused: subnet
@@ -828,6 +862,7 @@ WARNING: translation string unused: tor accounting period daily
 WARNING: translation string unused: tor accounting period monthly
 WARNING: translation string unused: tor accounting period weekly
 WARNING: translation string unused: tor bridge enabled
+WARNING: translation string unused: tor daemon
 WARNING: translation string unused: tor errmsg invalid node id
 WARNING: translation string unused: tor exit country
 WARNING: translation string unused: tor guard country
@@ -977,6 +1012,11 @@ WARNING: translation string unused: zoneconf val vlan amount assignment error
 WARNING: translation string unused: zoneconf val vlan tag assignment error
 WARNING: translation string unused: zoneconf val vlan tag range error
 WARNING: translation string unused: zoneconf val zoneslave amount error
+WARNING: untranslated string: AES-128-CBC = AES - CBC Mode - 128 Bit
+WARNING: untranslated string: AES-128-GCM = AES - GCM Mode - 128 Bit
+WARNING: untranslated string: AES-256-CBC = AES - CBC Mode - 256 Bit
+WARNING: untranslated string: AES-256-GCM = AES - GCM Mode - 256 Bit
+WARNING: untranslated string: CHACHA20-POLY1305 = ChaCha20-Poly1305
 WARNING: untranslated string: Captive ACTIVATE = unknown string
 WARNING: untranslated string: Captive clients = unknown string
 WARNING: untranslated string: ca name must only contain characters and spaces = unknown string
@@ -1021,12 +1061,30 @@ WARNING: untranslated string: info messages = unknown string
 WARNING: untranslated string: mdstat = Mdstat
 WARNING: untranslated string: no data = unknown string
 WARNING: untranslated string: online = Online
+WARNING: untranslated string: ovpn ciphers = Ciphers
+WARNING: untranslated string: ovpn crypto settings = Cryptographic Settings
+WARNING: untranslated string: ovpn dhcp settings = DHCP Settings
+WARNING: untranslated string: ovpn dynamic client subnet = Dynamic Client Subnet
+WARNING: untranslated string: ovpn errmsg invalid route = Invalid route
+WARNING: untranslated string: ovpn fallback cipher = Fallback Cipher
+WARNING: untranslated string: ovpn fallback cipher help = This cipher is being used by clients that do not support cipher negotiation.
+WARNING: untranslated string: ovpn fqdn = FQDN
+WARNING: untranslated string: ovpn misc settings = Miscellaneous Settings
+WARNING: untranslated string: ovpn no cipher selected = No cipher selected
+WARNING: untranslated string: ovpn protocol settings = Protocol Settings
+WARNING: untranslated string: ovpn push default route = Push Default Route
+WARNING: untranslated string: ovpn roadwarrior settings = Roadwarrior Settings
+WARNING: untranslated string: ovpn routing settings = Routing Settings
+WARNING: untranslated string: ovpn transport protocol = Transport Protocol
+WARNING: untranslated string: ovpn unsupported cipher selected = Unknown cipher selected
 WARNING: untranslated string: pakfire ago = ago.
 WARNING: untranslated string: quality of service = Quality of Service
 WARNING: untranslated string: route config changed = unknown string
 WARNING: untranslated string: routing config added = unknown string
 WARNING: untranslated string: routing config changed = unknown string
 WARNING: untranslated string: routing table = unknown string
+WARNING: untranslated string: rss = RSS
+WARNING: untranslated string: rss long = Resident Set Size
 WARNING: untranslated string: wio = unknown string
 WARNING: untranslated string: wio checked = unknown string
 WARNING: untranslated string: wio cron = unknown string
diff --git a/doc/language_issues.fr b/doc/language_issues.fr
index 9409e22197..a25b012ad6 100644
--- a/doc/language_issues.fr
+++ b/doc/language_issues.fr
@@ -27,11 +27,11 @@ WARNING: translation string unused: Captive vout
 WARNING: translation string unused: ConnSched scheduler
 WARNING: translation string unused: ConnSched select profile
 WARNING: translation string unused: Daily
-WARNING: translation string unused: Disabled
 WARNING: translation string unused: Existing Files
 WARNING: translation string unused: HDD temperature
 WARNING: translation string unused: Level7 rule
 WARNING: translation string unused: Local VPN IP
+WARNING: translation string unused: OVPN
 WARNING: translation string unused: Pages
 WARNING: translation string unused: Ping
 WARNING: translation string unused: Queuelenght
@@ -134,6 +134,7 @@ WARNING: translation string unused: apply
 WARNING: translation string unused: archive not exist
 WARNING: translation string unused: artist
 WARNING: translation string unused: attemps
+WARNING: translation string unused: attention
 WARNING: translation string unused: avoid dod
 WARNING: translation string unused: backup archive
 WARNING: translation string unused: backup clear archive
@@ -176,8 +177,12 @@ WARNING: translation string unused: cannot enable both nat traversal and compres
 WARNING: translation string unused: cant enable xtaccess
 WARNING: translation string unused: capsinactive
 WARNING: translation string unused: ccd err iroute
+WARNING: translation string unused: ccd err name
 WARNING: translation string unused: ccd err netadr
+WARNING: translation string unused: ccd hint
+WARNING: translation string unused: ccd iroutehint
 WARNING: translation string unused: ccd maxclients
+WARNING: translation string unused: ccd noaddnet
 WARNING: translation string unused: cfg restart
 WARNING: translation string unused: change share
 WARNING: translation string unused: check for net traffic update
@@ -205,6 +210,8 @@ WARNING: translation string unused: cpu frequency per
 WARNING: translation string unused: cpu usage per
 WARNING: translation string unused: create mask
 WARNING: translation string unused: create new backup
+WARNING: translation string unused: crypto error
+WARNING: translation string unused: crypto warning
 WARNING: translation string unused: cryptographic settings
 WARNING: translation string unused: current media
 WARNING: translation string unused: current ovpn
@@ -238,6 +245,7 @@ WARNING: translation string unused: destination ip bad
 WARNING: translation string unused: destination ip or net
 WARNING: translation string unused: destination net
 WARNING: translation string unused: destination port overlaps
+WARNING: translation string unused: dh
 WARNING: translation string unused: dhcp base ip fixed lease
 WARNING: translation string unused: dhcp create fixed leases
 WARNING: translation string unused: dhcp fixed lease err1
@@ -245,6 +253,7 @@ WARNING: translation string unused: dhcp fixed lease help1
 WARNING: translation string unused: dhcp mode
 WARNING: translation string unused: dhcp server disabled on blue interface
 WARNING: translation string unused: dhcp server enabled on blue interface
+WARNING: translation string unused: dhcp-options
 WARNING: translation string unused: dial user password
 WARNING: translation string unused: dial user password has been changed
 WARNING: translation string unused: dialup settings
@@ -256,6 +265,7 @@ WARNING: translation string unused: disk access
 WARNING: translation string unused: display charset
 WARNING: translation string unused: display traffic at home
 WARNING: translation string unused: display webinterface effects
+WARNING: translation string unused: dl client arch insecure
 WARNING: translation string unused: dmz pinhole configuration
 WARNING: translation string unused: dmz pinhole rule added
 WARNING: translation string unused: dmz pinhole rule removed
@@ -381,6 +391,7 @@ WARNING: translation string unused: fwhost Custom Host
 WARNING: translation string unused: fwhost Custom Network
 WARNING: translation string unused: fwhost IpSec Host
 WARNING: translation string unused: fwhost IpSec Network
+WARNING: translation string unused: fwhost OpenVPN N-2-N
 WARNING: translation string unused: fwhost OpenVPN static host
 WARNING: translation string unused: fwhost OpenVPN static network
 WARNING: translation string unused: fwhost Standard Network
@@ -457,6 +468,9 @@ WARNING: translation string unused: intrusion detection system2
 WARNING: translation string unused: invalid cache size
 WARNING: translation string unused: invalid date entered
 WARNING: translation string unused: invalid downlink speed
+WARNING: translation string unused: invalid input for keepalive 1
+WARNING: translation string unused: invalid input for keepalive 1:2
+WARNING: translation string unused: invalid input for keepalive 2
 WARNING: translation string unused: invalid input for oink code
 WARNING: translation string unused: invalid loaded file
 WARNING: translation string unused: invalid md5sum
@@ -475,6 +489,7 @@ WARNING: translation string unused: ipblocklist category invalid
 WARNING: translation string unused: ipblocklist category reputation
 WARNING: translation string unused: ipblocklist category scanner
 WARNING: translation string unused: ipfire side
+WARNING: translation string unused: ipfire side is invalid
 WARNING: translation string unused: ipsec no connections
 WARNING: translation string unused: iptable rules
 WARNING: translation string unused: javascript menu error1
@@ -493,6 +508,7 @@ WARNING: translation string unused: load printer
 WARNING: translation string unused: loaded modules
 WARNING: translation string unused: local hard disk
 WARNING: translation string unused: local master
+WARNING: translation string unused: local vpn hostname/ip
 WARNING: translation string unused: localkey
 WARNING: translation string unused: localkeyfile
 WARNING: translation string unused: locationblock country code
@@ -503,6 +519,7 @@ WARNING: translation string unused: log level
 WARNING: translation string unused: log var messages
 WARNING: translation string unused: log view
 WARNING: translation string unused: log viewer
+WARNING: translation string unused: log-options
 WARNING: translation string unused: logging
 WARNING: translation string unused: loosedirectorychecking
 WARNING: translation string unused: ls_dhcpd
@@ -538,6 +555,7 @@ WARNING: translation string unused: meaning
 WARNING: translation string unused: memory usage per
 WARNING: translation string unused: messages logging
 WARNING: translation string unused: min size
+WARNING: translation string unused: misc-options
 WARNING: translation string unused: missing dat
 WARNING: translation string unused: missing gz
 WARNING: translation string unused: modem on com1
@@ -623,10 +641,15 @@ WARNING: translation string unused: outgoing firewall reset
 WARNING: translation string unused: outgoing firewall view group
 WARNING: translation string unused: outgoing firewall warning
 WARNING: translation string unused: override mtu
+WARNING: translation string unused: ovpn add conf
 WARNING: translation string unused: ovpn config
+WARNING: translation string unused: ovpn crypt options
 WARNING: translation string unused: ovpn device
 WARNING: translation string unused: ovpn dl
 WARNING: translation string unused: ovpn engines
+WARNING: translation string unused: ovpn errmsg green already pushed
+WARNING: translation string unused: ovpn errmsg invalid ip or mask
+WARNING: translation string unused: ovpn error md5
 WARNING: translation string unused: ovpn generating the root and host certificates
 WARNING: translation string unused: ovpn log
 WARNING: translation string unused: ovpn mtu-disc
@@ -636,7 +659,13 @@ WARNING: translation string unused: ovpn mtu-disc no
 WARNING: translation string unused: ovpn mtu-disc off
 WARNING: translation string unused: ovpn mtu-disc with mssfix or fragment
 WARNING: translation string unused: ovpn mtu-disc yes
+WARNING: translation string unused: ovpn on blue
+WARNING: translation string unused: ovpn on orange
+WARNING: translation string unused: ovpn on red
 WARNING: translation string unused: ovpn reneg sec
+WARNING: translation string unused: ovpn routes push options
+WARNING: translation string unused: ovpn server status
+WARNING: translation string unused: ovpn warning rfc3280
 WARNING: translation string unused: ovpn_fastio
 WARNING: translation string unused: ovpn_fragment
 WARNING: translation string unused: ovpn_mssfix
@@ -709,6 +738,7 @@ WARNING: translation string unused: reset shares
 WARNING: translation string unused: resetglobals
 WARNING: translation string unused: resetpolicy
 WARNING: translation string unused: resetshares
+WARNING: translation string unused: restart ovpn server
 WARNING: translation string unused: restore hardware settings
 WARNING: translation string unused: restore settings
 WARNING: translation string unused: root
@@ -732,6 +762,7 @@ WARNING: translation string unused: selecttraffic
 WARNING: translation string unused: send email notification
 WARNING: translation string unused: send test mail
 WARNING: translation string unused: server reserved
+WARNING: translation string unused: server restart
 WARNING: translation string unused: server string
 WARNING: translation string unused: service added
 WARNING: translation string unused: service removed
@@ -742,6 +773,7 @@ WARNING: translation string unused: set
 WARNING: translation string unused: shaping add options
 WARNING: translation string unused: shaping list options
 WARNING: translation string unused: show areas
+WARNING: translation string unused: show dh
 WARNING: translation string unused: show last x lines
 WARNING: translation string unused: show lines
 WARNING: translation string unused: show share options
@@ -783,6 +815,8 @@ WARNING: translation string unused: ssport forwarding
 WARNING: translation string unused: ssproxy graphs
 WARNING: translation string unused: sssystem status
 WARNING: translation string unused: sstraffic graphs
+WARNING: translation string unused: start ovpn server
+WARNING: translation string unused: stop ovpn server
 WARNING: translation string unused: subject test
 WARNING: translation string unused: subject warn
 WARNING: translation string unused: subnet
@@ -819,6 +853,7 @@ WARNING: translation string unused: tor accounting period daily
 WARNING: translation string unused: tor accounting period monthly
 WARNING: translation string unused: tor accounting period weekly
 WARNING: translation string unused: tor bridge enabled
+WARNING: translation string unused: tor daemon
 WARNING: translation string unused: tor errmsg invalid node id
 WARNING: translation string unused: tor exit country
 WARNING: translation string unused: tor guard country
@@ -958,6 +993,11 @@ WARNING: translation string unused: zoneconf val vlan amount assignment error
 WARNING: translation string unused: zoneconf val vlan tag assignment error
 WARNING: translation string unused: zoneconf val vlan tag range error
 WARNING: translation string unused: zoneconf val zoneslave amount error
+WARNING: untranslated string: AES-128-CBC = AES - CBC Mode - 128 Bit
+WARNING: untranslated string: AES-128-GCM = AES - GCM Mode - 128 Bit
+WARNING: untranslated string: AES-256-CBC = AES - CBC Mode - 256 Bit
+WARNING: untranslated string: AES-256-GCM = AES - GCM Mode - 256 Bit
+WARNING: untranslated string: CHACHA20-POLY1305 = ChaCha20-Poly1305
 WARNING: untranslated string: allowed subnets = Allowed Subnets
 WARNING: untranslated string: bypassed = Bypassed
 WARNING: untranslated string: ca name must only contain characters and spaces = unknown string
@@ -1025,7 +1065,23 @@ WARNING: untranslated string: malformed public key = Malformed Public Key
 WARNING: untranslated string: mdstat = Mdstat
 WARNING: untranslated string: online = Online
 WARNING: untranslated string: oops something went wrong = Oops, something went wrong...
+WARNING: untranslated string: ovpn ciphers = Ciphers
+WARNING: untranslated string: ovpn crypto settings = Cryptographic Settings
+WARNING: untranslated string: ovpn dhcp settings = DHCP Settings
+WARNING: untranslated string: ovpn dynamic client subnet = Dynamic Client Subnet
+WARNING: untranslated string: ovpn errmsg invalid route = Invalid route
+WARNING: untranslated string: ovpn fallback cipher = Fallback Cipher
+WARNING: untranslated string: ovpn fallback cipher help = This cipher is being used by clients that do not support cipher negotiation.
+WARNING: untranslated string: ovpn fqdn = FQDN
+WARNING: untranslated string: ovpn misc settings = Miscellaneous Settings
+WARNING: untranslated string: ovpn no cipher selected = No cipher selected
+WARNING: untranslated string: ovpn protocol settings = Protocol Settings
+WARNING: untranslated string: ovpn push default route = Push Default Route
 WARNING: untranslated string: ovpn roadwarrior server = OpenVPN Roadwarrior Server
+WARNING: untranslated string: ovpn roadwarrior settings = Roadwarrior Settings
+WARNING: untranslated string: ovpn routing settings = Routing Settings
+WARNING: untranslated string: ovpn transport protocol = Transport Protocol
+WARNING: untranslated string: ovpn unsupported cipher selected = Unknown cipher selected
 WARNING: untranslated string: pakfire ago = ago.
 WARNING: untranslated string: password has quotation mark = Password contains an illegal double quotation mark.
 WARNING: untranslated string: processors = Processors
@@ -1038,6 +1094,8 @@ WARNING: untranslated string: remote subnets = Remote Subnets
 WARNING: untranslated string: routing = Routing
 WARNING: untranslated string: routing config added = unknown string
 WARNING: untranslated string: routing config changed = unknown string
+WARNING: untranslated string: rss = RSS
+WARNING: untranslated string: rss long = Resident Set Size
 WARNING: untranslated string: scanned = Scanned
 WARNING: untranslated string: system time = System Time (as of last page load)
 WARNING: untranslated string: timeformat = %Y-%m-%d at %H:%M:%S %Z
diff --git a/doc/language_issues.it b/doc/language_issues.it
index 4465dbf4d9..3f1c61c342 100644
--- a/doc/language_issues.it
+++ b/doc/language_issues.it
@@ -6,6 +6,7 @@ WARNING: translation string unused: Existing Files
 WARNING: translation string unused: HDD temperature
 WARNING: translation string unused: Level7 rule
 WARNING: translation string unused: Local VPN IP
+WARNING: translation string unused: OVPN
 WARNING: translation string unused: Pages
 WARNING: translation string unused: Ping
 WARNING: translation string unused: Queuelenght
@@ -104,6 +105,7 @@ WARNING: translation string unused: apply
 WARNING: translation string unused: archive not exist
 WARNING: translation string unused: artist
 WARNING: translation string unused: attemps
+WARNING: translation string unused: attention
 WARNING: translation string unused: avoid dod
 WARNING: translation string unused: backup archive
 WARNING: translation string unused: backup clear archive
@@ -147,7 +149,11 @@ WARNING: translation string unused: cannot enable both nat traversal and compres
 WARNING: translation string unused: cant enable xtaccess
 WARNING: translation string unused: capsinactive
 WARNING: translation string unused: ccd err iroute
+WARNING: translation string unused: ccd err name
 WARNING: translation string unused: ccd err netadr
+WARNING: translation string unused: ccd hint
+WARNING: translation string unused: ccd iroutehint
+WARNING: translation string unused: ccd noaddnet
 WARNING: translation string unused: cfg restart
 WARNING: translation string unused: change share
 WARNING: translation string unused: check for net traffic update
@@ -214,6 +220,7 @@ WARNING: translation string unused: dhcp fixed lease help1
 WARNING: translation string unused: dhcp mode
 WARNING: translation string unused: dhcp server disabled on blue interface
 WARNING: translation string unused: dhcp server enabled on blue interface
+WARNING: translation string unused: dhcp-options
 WARNING: translation string unused: dial user password
 WARNING: translation string unused: dial user password has been changed
 WARNING: translation string unused: dialup settings
@@ -345,6 +352,7 @@ WARNING: translation string unused: fwhost Custom Host
 WARNING: translation string unused: fwhost Custom Network
 WARNING: translation string unused: fwhost IpSec Host
 WARNING: translation string unused: fwhost IpSec Network
+WARNING: translation string unused: fwhost OpenVPN N-2-N
 WARNING: translation string unused: fwhost OpenVPN static host
 WARNING: translation string unused: fwhost OpenVPN static network
 WARNING: translation string unused: fwhost Standard Network
@@ -423,6 +431,9 @@ WARNING: translation string unused: intrusion detection system2
 WARNING: translation string unused: invalid cache size
 WARNING: translation string unused: invalid date entered
 WARNING: translation string unused: invalid downlink speed
+WARNING: translation string unused: invalid input for keepalive 1
+WARNING: translation string unused: invalid input for keepalive 1:2
+WARNING: translation string unused: invalid input for keepalive 2
 WARNING: translation string unused: invalid input for oink code
 WARNING: translation string unused: invalid loaded file
 WARNING: translation string unused: invalid md5sum
@@ -434,6 +445,7 @@ WARNING: translation string unused: invalid users
 WARNING: translation string unused: invert
 WARNING: translation string unused: ip address in use
 WARNING: translation string unused: ipfire side
+WARNING: translation string unused: ipfire side is invalid
 WARNING: translation string unused: ipsec no connections
 WARNING: translation string unused: iptable rules
 WARNING: translation string unused: javascript menu error1
@@ -451,6 +463,7 @@ WARNING: translation string unused: load printer
 WARNING: translation string unused: loaded modules
 WARNING: translation string unused: local hard disk
 WARNING: translation string unused: local master
+WARNING: translation string unused: local vpn hostname/ip
 WARNING: translation string unused: localkey
 WARNING: translation string unused: localkeyfile
 WARNING: translation string unused: log enabled
@@ -458,6 +471,7 @@ WARNING: translation string unused: log level
 WARNING: translation string unused: log var messages
 WARNING: translation string unused: log view
 WARNING: translation string unused: log viewer
+WARNING: translation string unused: log-options
 WARNING: translation string unused: logging
 WARNING: translation string unused: loosedirectorychecking
 WARNING: translation string unused: ls_dhcpd
@@ -493,6 +507,7 @@ WARNING: translation string unused: meaning
 WARNING: translation string unused: memory usage per
 WARNING: translation string unused: messages logging
 WARNING: translation string unused: min size
+WARNING: translation string unused: misc-options
 WARNING: translation string unused: missing dat
 WARNING: translation string unused: missing gz
 WARNING: translation string unused: modem on com1
@@ -578,9 +593,12 @@ WARNING: translation string unused: outgoing firewall view group
 WARNING: translation string unused: outgoing firewall warning
 WARNING: translation string unused: override mtu
 WARNING: translation string unused: ovpn config
+WARNING: translation string unused: ovpn crypt options
 WARNING: translation string unused: ovpn device
 WARNING: translation string unused: ovpn dl
 WARNING: translation string unused: ovpn engines
+WARNING: translation string unused: ovpn errmsg green already pushed
+WARNING: translation string unused: ovpn errmsg invalid ip or mask
 WARNING: translation string unused: ovpn generating the root and host certificates
 WARNING: translation string unused: ovpn hmac
 WARNING: translation string unused: ovpn log
@@ -591,7 +609,12 @@ WARNING: translation string unused: ovpn mtu-disc no
 WARNING: translation string unused: ovpn mtu-disc off
 WARNING: translation string unused: ovpn mtu-disc with mssfix or fragment
 WARNING: translation string unused: ovpn mtu-disc yes
+WARNING: translation string unused: ovpn on blue
+WARNING: translation string unused: ovpn on orange
+WARNING: translation string unused: ovpn on red
 WARNING: translation string unused: ovpn reneg sec
+WARNING: translation string unused: ovpn routes push options
+WARNING: translation string unused: ovpn server status
 WARNING: translation string unused: ovpn_fastio
 WARNING: translation string unused: ovpn_mssfix
 WARNING: translation string unused: ovpn_mtudisc
@@ -662,6 +685,7 @@ WARNING: translation string unused: reset shares
 WARNING: translation string unused: resetglobals
 WARNING: translation string unused: resetpolicy
 WARNING: translation string unused: resetshares
+WARNING: translation string unused: restart ovpn server
 WARNING: translation string unused: restore hardware settings
 WARNING: translation string unused: restore settings
 WARNING: translation string unused: root
@@ -684,6 +708,7 @@ WARNING: translation string unused: selecttraffic
 WARNING: translation string unused: send email notification
 WARNING: translation string unused: send test mail
 WARNING: translation string unused: server reserved
+WARNING: translation string unused: server restart
 WARNING: translation string unused: server string
 WARNING: translation string unused: service added
 WARNING: translation string unused: service removed
@@ -737,6 +762,8 @@ WARNING: translation string unused: ssport forwarding
 WARNING: translation string unused: ssproxy graphs
 WARNING: translation string unused: sssystem status
 WARNING: translation string unused: sstraffic graphs
+WARNING: translation string unused: start ovpn server
+WARNING: translation string unused: stop ovpn server
 WARNING: translation string unused: subject test
 WARNING: translation string unused: subject warn
 WARNING: translation string unused: subnet
@@ -773,6 +800,7 @@ WARNING: translation string unused: tor accounting period daily
 WARNING: translation string unused: tor accounting period monthly
 WARNING: translation string unused: tor accounting period weekly
 WARNING: translation string unused: tor bridge enabled
+WARNING: translation string unused: tor daemon
 WARNING: translation string unused: tor errmsg invalid node id
 WARNING: translation string unused: tor exit country
 WARNING: translation string unused: traffic back
@@ -895,6 +923,11 @@ WARNING: translation string unused: xtaccess bad transfert
 WARNING: translation string unused: year-graph
 WARNING: translation string unused: yearly firewallhits
 WARNING: untranslated string: 24 hours = 24 Hours
+WARNING: untranslated string: AES-128-CBC = AES - CBC Mode - 128 Bit
+WARNING: untranslated string: AES-128-GCM = AES - GCM Mode - 128 Bit
+WARNING: untranslated string: AES-256-CBC = AES - CBC Mode - 256 Bit
+WARNING: untranslated string: AES-256-GCM = AES - GCM Mode - 256 Bit
+WARNING: untranslated string: CHACHA20-POLY1305 = ChaCha20-Poly1305
 WARNING: untranslated string: Captive = Captive Portal
 WARNING: untranslated string: Captive ACTIVATE = unknown string
 WARNING: untranslated string: Captive GAIN ACCESS = GAIN ACCESS
@@ -929,6 +962,7 @@ WARNING: untranslated string: Captive upload logo recommendations = (PNG or JPEG
 WARNING: untranslated string: Captive valid for = Valid for
 WARNING: untranslated string: Captive vouchervalid = Allowed time for this coupon
 WARNING: untranslated string: Captive wrong type = Uploaded file has wrong filetype
+WARNING: untranslated string: Disabled = Disabled
 WARNING: untranslated string: MTU settings = MTU settings:
 WARNING: untranslated string: Number of Countries for the pie chart = Number of Countries for the pie chart
 WARNING: untranslated string: access point name = Access Point Name
@@ -983,13 +1017,10 @@ WARNING: untranslated string: check all = Check all
 WARNING: untranslated string: configuration file = Configuration File
 WARNING: untranslated string: core update = Core-Update
 WARNING: untranslated string: cpu frequency = CPU frequency
-WARNING: untranslated string: crypto error = Cryptographic error
-WARNING: untranslated string: crypto warning = Cryptographic warning
 WARNING: untranslated string: dangerous = Dangerous
 WARNING: untranslated string: data transfer = Data Transfer
 WARNING: untranslated string: default IP address = Default IP Address
 WARNING: untranslated string: desired = Desired
-WARNING: untranslated string: dh = Diffie-Hellman-Parameter
 WARNING: untranslated string: dhcp deny known clients: = Deny known clients:
 WARNING: untranslated string: dhcp dns enable update = Enable DNS Update (RFC2136):
 WARNING: untranslated string: dhcp dns key name = Key Name
@@ -1001,7 +1032,6 @@ WARNING: untranslated string: dhcp make fixed lease = Add to fix leases
 WARNING: untranslated string: dhcp valid range required when deny known clients checked = Valid range required when "Deny known clients:" is checked
 WARNING: untranslated string: disable = Disable
 WARNING: untranslated string: disconnected = Disconnected
-WARNING: untranslated string: dl client arch insecure = Download insecure Client Package (zip)
 WARNING: untranslated string: dns check servers = Check DNS Servers
 WARNING: untranslated string: dns configuration = DNS Configuration
 WARNING: untranslated string: dns enable safe-search = Enable Safe Search
@@ -1266,13 +1296,26 @@ WARNING: untranslated string: optional = Optional
 WARNING: untranslated string: otp qrcode = OTP QRCode
 WARNING: untranslated string: outgoing compression in bytes per second = Outgoing compression
 WARNING: untranslated string: outgoing overhead in bytes per second = Outgoing Overhead
-WARNING: untranslated string: ovpn add conf = Additional configuration
+WARNING: untranslated string: ovpn ciphers = Ciphers
 WARNING: untranslated string: ovpn connection name = Connection Name
-WARNING: untranslated string: ovpn error md5 = You host certificate uses MD5 for the signature which is not accepted anymore. <br>Please update to the latest IPFire version and generate a new root and host certificate.</br><br>All OpenVPN clients needs then to be renewed!</br>
+WARNING: untranslated string: ovpn crypto settings = Cryptographic Settings
+WARNING: untranslated string: ovpn dhcp settings = DHCP Settings
+WARNING: untranslated string: ovpn dynamic client subnet = Dynamic Client Subnet
+WARNING: untranslated string: ovpn errmsg invalid route = Invalid route
+WARNING: untranslated string: ovpn fallback cipher = Fallback Cipher
+WARNING: untranslated string: ovpn fallback cipher help = This cipher is being used by clients that do not support cipher negotiation.
+WARNING: untranslated string: ovpn fqdn = FQDN
+WARNING: untranslated string: ovpn misc settings = Miscellaneous Settings
+WARNING: untranslated string: ovpn no cipher selected = No cipher selected
+WARNING: untranslated string: ovpn protocol settings = Protocol Settings
+WARNING: untranslated string: ovpn push default route = Push Default Route
 WARNING: untranslated string: ovpn roadwarrior server = OpenVPN Roadwarrior Server
+WARNING: untranslated string: ovpn roadwarrior settings = Roadwarrior Settings
+WARNING: untranslated string: ovpn routing settings = Routing Settings
 WARNING: untranslated string: ovpn rw connection log = OpenVPN Roadwarrior Connections Log
 WARNING: untranslated string: ovpn tls auth = TLS Channel Protection:
-WARNING: untranslated string: ovpn warning rfc3280 = Your host certificate is not RFC3280 compliant. <br>Please update to the latest IPFire version and generate as soon as possible a new root and host certificate.</br><br>All OpenVPN clients needs then to be renewed!</br>
+WARNING: untranslated string: ovpn transport protocol = Transport Protocol
+WARNING: untranslated string: ovpn unsupported cipher selected = Unknown cipher selected
 WARNING: untranslated string: pak update = Update
 WARNING: untranslated string: pakfire already busy = Pakfire is already performing a task. Please try again later.
 WARNING: untranslated string: pakfire finished = Pakfire has finished! Returning...
@@ -1313,6 +1356,8 @@ WARNING: untranslated string: routing = Routing
 WARNING: untranslated string: routing config added = unknown string
 WARNING: untranslated string: routing config changed = unknown string
 WARNING: untranslated string: routing table = unknown string
+WARNING: untranslated string: rss = RSS
+WARNING: untranslated string: rss long = Resident Set Size
 WARNING: untranslated string: samba join a domain = Join a domain
 WARNING: untranslated string: samba join domain = Join domain
 WARNING: untranslated string: samba server role member = Domain Member
@@ -1322,7 +1367,6 @@ WARNING: untranslated string: search = Search
 WARNING: untranslated string: secret = Secret
 WARNING: untranslated string: sent = Sent
 WARNING: untranslated string: service boot setting unavailable = No valid runlevel symlink was found for the initscript of this service.
-WARNING: untranslated string: show dh = Show Diffie-Hellman parameters
 WARNING: untranslated string: show otp qrcode = Show OTP QRCode
 WARNING: untranslated string: smb daemon = SMB Daemon
 WARNING: untranslated string: smt disabled = Simultaneous Multi-Threading (SMT) is disabled
diff --git a/doc/language_issues.nl b/doc/language_issues.nl
index 1dfa01f5ad..9b4b279e15 100644
--- a/doc/language_issues.nl
+++ b/doc/language_issues.nl
@@ -6,6 +6,7 @@ WARNING: translation string unused: Existing Files
 WARNING: translation string unused: HDD temperature
 WARNING: translation string unused: Level7 rule
 WARNING: translation string unused: Local VPN IP
+WARNING: translation string unused: OVPN
 WARNING: translation string unused: Pages
 WARNING: translation string unused: Ping
 WARNING: translation string unused: Queuelenght
@@ -104,6 +105,7 @@ WARNING: translation string unused: apply
 WARNING: translation string unused: archive not exist
 WARNING: translation string unused: artist
 WARNING: translation string unused: attemps
+WARNING: translation string unused: attention
 WARNING: translation string unused: avoid dod
 WARNING: translation string unused: backup archive
 WARNING: translation string unused: backup clear archive
@@ -147,7 +149,11 @@ WARNING: translation string unused: cannot enable both nat traversal and compres
 WARNING: translation string unused: cant enable xtaccess
 WARNING: translation string unused: capsinactive
 WARNING: translation string unused: ccd err iroute
+WARNING: translation string unused: ccd err name
 WARNING: translation string unused: ccd err netadr
+WARNING: translation string unused: ccd hint
+WARNING: translation string unused: ccd iroutehint
+WARNING: translation string unused: ccd noaddnet
 WARNING: translation string unused: cfg restart
 WARNING: translation string unused: change share
 WARNING: translation string unused: check for net traffic update
@@ -215,6 +221,7 @@ WARNING: translation string unused: dhcp fixed lease help1
 WARNING: translation string unused: dhcp mode
 WARNING: translation string unused: dhcp server disabled on blue interface
 WARNING: translation string unused: dhcp server enabled on blue interface
+WARNING: translation string unused: dhcp-options
 WARNING: translation string unused: dial user password
 WARNING: translation string unused: dial user password has been changed
 WARNING: translation string unused: dialup settings
@@ -226,6 +233,7 @@ WARNING: translation string unused: disk access
 WARNING: translation string unused: display charset
 WARNING: translation string unused: display traffic at home
 WARNING: translation string unused: display webinterface effects
+WARNING: translation string unused: dl client arch insecure
 WARNING: translation string unused: dmz pinhole configuration
 WARNING: translation string unused: dmz pinhole rule added
 WARNING: translation string unused: dmz pinhole rule removed
@@ -346,6 +354,7 @@ WARNING: translation string unused: fwhost Custom Host
 WARNING: translation string unused: fwhost Custom Network
 WARNING: translation string unused: fwhost IpSec Host
 WARNING: translation string unused: fwhost IpSec Network
+WARNING: translation string unused: fwhost OpenVPN N-2-N
 WARNING: translation string unused: fwhost OpenVPN static host
 WARNING: translation string unused: fwhost OpenVPN static network
 WARNING: translation string unused: fwhost Standard Network
@@ -425,6 +434,9 @@ WARNING: translation string unused: intrusion detection system2
 WARNING: translation string unused: invalid cache size
 WARNING: translation string unused: invalid date entered
 WARNING: translation string unused: invalid downlink speed
+WARNING: translation string unused: invalid input for keepalive 1
+WARNING: translation string unused: invalid input for keepalive 1:2
+WARNING: translation string unused: invalid input for keepalive 2
 WARNING: translation string unused: invalid input for oink code
 WARNING: translation string unused: invalid loaded file
 WARNING: translation string unused: invalid md5sum
@@ -436,6 +448,7 @@ WARNING: translation string unused: invalid users
 WARNING: translation string unused: invert
 WARNING: translation string unused: ip address in use
 WARNING: translation string unused: ipfire side
+WARNING: translation string unused: ipfire side is invalid
 WARNING: translation string unused: ipsec no connections
 WARNING: translation string unused: iptable rules
 WARNING: translation string unused: javascript menu error1
@@ -453,6 +466,7 @@ WARNING: translation string unused: load printer
 WARNING: translation string unused: loaded modules
 WARNING: translation string unused: local hard disk
 WARNING: translation string unused: local master
+WARNING: translation string unused: local vpn hostname/ip
 WARNING: translation string unused: localkey
 WARNING: translation string unused: localkeyfile
 WARNING: translation string unused: log enabled
@@ -460,6 +474,7 @@ WARNING: translation string unused: log level
 WARNING: translation string unused: log var messages
 WARNING: translation string unused: log view
 WARNING: translation string unused: log viewer
+WARNING: translation string unused: log-options
 WARNING: translation string unused: logging
 WARNING: translation string unused: loosedirectorychecking
 WARNING: translation string unused: ls_dhcpd
@@ -495,6 +510,7 @@ WARNING: translation string unused: meaning
 WARNING: translation string unused: memory usage per
 WARNING: translation string unused: messages logging
 WARNING: translation string unused: min size
+WARNING: translation string unused: misc-options
 WARNING: translation string unused: missing dat
 WARNING: translation string unused: missing gz
 WARNING: translation string unused: modem on com1
@@ -582,6 +598,8 @@ WARNING: translation string unused: override mtu
 WARNING: translation string unused: ovpn config
 WARNING: translation string unused: ovpn device
 WARNING: translation string unused: ovpn dl
+WARNING: translation string unused: ovpn errmsg green already pushed
+WARNING: translation string unused: ovpn errmsg invalid ip or mask
 WARNING: translation string unused: ovpn log
 WARNING: translation string unused: ovpn mtu-disc
 WARNING: translation string unused: ovpn mtu-disc and mtu not 1500
@@ -590,6 +608,11 @@ WARNING: translation string unused: ovpn mtu-disc no
 WARNING: translation string unused: ovpn mtu-disc off
 WARNING: translation string unused: ovpn mtu-disc with mssfix or fragment
 WARNING: translation string unused: ovpn mtu-disc yes
+WARNING: translation string unused: ovpn on blue
+WARNING: translation string unused: ovpn on orange
+WARNING: translation string unused: ovpn on red
+WARNING: translation string unused: ovpn routes push options
+WARNING: translation string unused: ovpn server status
 WARNING: translation string unused: ovpn_fastio
 WARNING: translation string unused: ovpn_fragment
 WARNING: translation string unused: ovpn_mssfix
@@ -661,6 +684,7 @@ WARNING: translation string unused: reset shares
 WARNING: translation string unused: resetglobals
 WARNING: translation string unused: resetpolicy
 WARNING: translation string unused: resetshares
+WARNING: translation string unused: restart ovpn server
 WARNING: translation string unused: restore hardware settings
 WARNING: translation string unused: restore settings
 WARNING: translation string unused: root
@@ -683,6 +707,7 @@ WARNING: translation string unused: selecttraffic
 WARNING: translation string unused: send email notification
 WARNING: translation string unused: send test mail
 WARNING: translation string unused: server reserved
+WARNING: translation string unused: server restart
 WARNING: translation string unused: server string
 WARNING: translation string unused: service added
 WARNING: translation string unused: service removed
@@ -736,6 +761,8 @@ WARNING: translation string unused: ssport forwarding
 WARNING: translation string unused: ssproxy graphs
 WARNING: translation string unused: sssystem status
 WARNING: translation string unused: sstraffic graphs
+WARNING: translation string unused: start ovpn server
+WARNING: translation string unused: stop ovpn server
 WARNING: translation string unused: subject test
 WARNING: translation string unused: subject warn
 WARNING: translation string unused: subnet
@@ -773,6 +800,7 @@ WARNING: translation string unused: tor accounting period daily
 WARNING: translation string unused: tor accounting period monthly
 WARNING: translation string unused: tor accounting period weekly
 WARNING: translation string unused: tor bridge enabled
+WARNING: translation string unused: tor daemon
 WARNING: translation string unused: tor errmsg invalid node id
 WARNING: translation string unused: tor exit country
 WARNING: translation string unused: traffic back
@@ -895,6 +923,11 @@ WARNING: translation string unused: xtaccess bad transfert
 WARNING: translation string unused: year-graph
 WARNING: translation string unused: yearly firewallhits
 WARNING: untranslated string: 24 hours = 24 Hours
+WARNING: untranslated string: AES-128-CBC = AES - CBC Mode - 128 Bit
+WARNING: untranslated string: AES-128-GCM = AES - GCM Mode - 128 Bit
+WARNING: untranslated string: AES-256-CBC = AES - CBC Mode - 256 Bit
+WARNING: untranslated string: AES-256-GCM = AES - GCM Mode - 256 Bit
+WARNING: untranslated string: CHACHA20-POLY1305 = ChaCha20-Poly1305
 WARNING: untranslated string: Captive = Captive Portal
 WARNING: untranslated string: Captive ACTIVATE = unknown string
 WARNING: untranslated string: Captive GAIN ACCESS = GAIN ACCESS
@@ -929,6 +962,7 @@ WARNING: untranslated string: Captive upload logo recommendations = (PNG or JPEG
 WARNING: untranslated string: Captive valid for = Valid for
 WARNING: untranslated string: Captive vouchervalid = Allowed time for this coupon
 WARNING: untranslated string: Captive wrong type = Uploaded file has wrong filetype
+WARNING: untranslated string: Disabled = Disabled
 WARNING: untranslated string: MTU settings = MTU settings:
 WARNING: untranslated string: Number of Countries for the pie chart = Number of Countries for the pie chart
 WARNING: untranslated string: access point name = Access Point Name
@@ -984,15 +1018,12 @@ WARNING: untranslated string: capabilities = Capabilities
 WARNING: untranslated string: check all = Check all
 WARNING: untranslated string: configuration file = Configuration File
 WARNING: untranslated string: cpu frequency = CPU frequency
-WARNING: untranslated string: crypto error = Cryptographic error
-WARNING: untranslated string: crypto warning = Cryptographic warning
 WARNING: untranslated string: daemon login script = Daemon login script
 WARNING: untranslated string: dangerous = Dangerous
 WARNING: untranslated string: data transfer = Data Transfer
 WARNING: untranslated string: default = Default
 WARNING: untranslated string: default IP address = Default IP Address
 WARNING: untranslated string: desired = Desired
-WARNING: untranslated string: dh = Diffie-Hellman-Parameter
 WARNING: untranslated string: dhcp dns enable update = Enable DNS Update (RFC2136):
 WARNING: untranslated string: dhcp dns key name = Key Name
 WARNING: untranslated string: dhcp dns update = DNS Update
@@ -1289,15 +1320,27 @@ WARNING: untranslated string: optional = Optional
 WARNING: untranslated string: otp qrcode = OTP QRCode
 WARNING: untranslated string: outgoing compression in bytes per second = Outgoing compression
 WARNING: untranslated string: outgoing overhead in bytes per second = Outgoing Overhead
-WARNING: untranslated string: ovpn add conf = Additional configuration
+WARNING: untranslated string: ovpn ciphers = Ciphers
 WARNING: untranslated string: ovpn connection name = Connection Name
-WARNING: untranslated string: ovpn crypt options = Cryptographic options
-WARNING: untranslated string: ovpn error md5 = You host certificate uses MD5 for the signature which is not accepted anymore. <br>Please update to the latest IPFire version and generate a new root and host certificate.</br><br>All OpenVPN clients needs then to be renewed!</br>
+WARNING: untranslated string: ovpn crypto settings = Cryptographic Settings
+WARNING: untranslated string: ovpn dhcp settings = DHCP Settings
+WARNING: untranslated string: ovpn dynamic client subnet = Dynamic Client Subnet
+WARNING: untranslated string: ovpn errmsg invalid route = Invalid route
+WARNING: untranslated string: ovpn fallback cipher = Fallback Cipher
+WARNING: untranslated string: ovpn fallback cipher help = This cipher is being used by clients that do not support cipher negotiation.
+WARNING: untranslated string: ovpn fqdn = FQDN
 WARNING: untranslated string: ovpn ha = Hash algorithm
+WARNING: untranslated string: ovpn misc settings = Miscellaneous Settings
+WARNING: untranslated string: ovpn no cipher selected = No cipher selected
+WARNING: untranslated string: ovpn protocol settings = Protocol Settings
+WARNING: untranslated string: ovpn push default route = Push Default Route
 WARNING: untranslated string: ovpn roadwarrior server = OpenVPN Roadwarrior Server
+WARNING: untranslated string: ovpn roadwarrior settings = Roadwarrior Settings
+WARNING: untranslated string: ovpn routing settings = Routing Settings
 WARNING: untranslated string: ovpn rw connection log = OpenVPN Roadwarrior Connections Log
 WARNING: untranslated string: ovpn tls auth = TLS Channel Protection:
-WARNING: untranslated string: ovpn warning rfc3280 = Your host certificate is not RFC3280 compliant. <br>Please update to the latest IPFire version and generate as soon as possible a new root and host certificate.</br><br>All OpenVPN clients needs then to be renewed!</br>
+WARNING: untranslated string: ovpn transport protocol = Transport Protocol
+WARNING: untranslated string: ovpn unsupported cipher selected = Unknown cipher selected
 WARNING: untranslated string: pakfire already busy = Pakfire is already performing a task. Please try again later.
 WARNING: untranslated string: pakfire finished = Pakfire has finished! Returning...
 WARNING: untranslated string: pakfire finished error = Pakfire has finished! Errors occurred, please check the log output before proceeding.
@@ -1334,6 +1377,8 @@ WARNING: untranslated string: routing = Routing
 WARNING: untranslated string: routing config added = unknown string
 WARNING: untranslated string: routing config changed = unknown string
 WARNING: untranslated string: routing table = unknown string
+WARNING: untranslated string: rss = RSS
+WARNING: untranslated string: rss long = Resident Set Size
 WARNING: untranslated string: samba join a domain = Join a domain
 WARNING: untranslated string: samba join domain = Join domain
 WARNING: untranslated string: samba server role member = Domain Member
@@ -1342,7 +1387,6 @@ WARNING: untranslated string: scanned = Scanned
 WARNING: untranslated string: search = Search
 WARNING: untranslated string: secret = Secret
 WARNING: untranslated string: sent = Sent
-WARNING: untranslated string: show dh = Show Diffie-Hellman parameters
 WARNING: untranslated string: show otp qrcode = Show OTP QRCode
 WARNING: untranslated string: show tls-auth key = Show tls-auth key
 WARNING: untranslated string: smb daemon = SMB Daemon
diff --git a/doc/language_issues.pl b/doc/language_issues.pl
index c1479001e7..48ed3d4e8d 100644
--- a/doc/language_issues.pl
+++ b/doc/language_issues.pl
@@ -6,6 +6,7 @@ WARNING: translation string unused: Existing Files
 WARNING: translation string unused: HDD temperature
 WARNING: translation string unused: Level7 rule
 WARNING: translation string unused: Local VPN IP
+WARNING: translation string unused: OVPN
 WARNING: translation string unused: Pages
 WARNING: translation string unused: Ping
 WARNING: translation string unused: Queuelenght
@@ -204,6 +205,7 @@ WARNING: translation string unused: dhcp fixed lease help1
 WARNING: translation string unused: dhcp mode
 WARNING: translation string unused: dhcp server disabled on blue interface
 WARNING: translation string unused: dhcp server enabled on blue interface
+WARNING: translation string unused: dhcp-options
 WARNING: translation string unused: dial user password
 WARNING: translation string unused: dial user password has been changed
 WARNING: translation string unused: dialup settings
@@ -364,6 +366,9 @@ WARNING: translation string unused: intrusion detection system2
 WARNING: translation string unused: invalid cache size
 WARNING: translation string unused: invalid date entered
 WARNING: translation string unused: invalid downlink speed
+WARNING: translation string unused: invalid input for keepalive 1
+WARNING: translation string unused: invalid input for keepalive 1:2
+WARNING: translation string unused: invalid input for keepalive 2
 WARNING: translation string unused: invalid input for oink code
 WARNING: translation string unused: invalid loaded file
 WARNING: translation string unused: invalid md5sum
@@ -375,6 +380,7 @@ WARNING: translation string unused: invalid users
 WARNING: translation string unused: invert
 WARNING: translation string unused: ip address in use
 WARNING: translation string unused: ipfire side
+WARNING: translation string unused: ipfire side is invalid
 WARNING: translation string unused: iptable rules
 WARNING: translation string unused: javascript menu error1
 WARNING: translation string unused: javascript menu error2
@@ -391,6 +397,7 @@ WARNING: translation string unused: load printer
 WARNING: translation string unused: loaded modules
 WARNING: translation string unused: local hard disk
 WARNING: translation string unused: local master
+WARNING: translation string unused: local vpn hostname/ip
 WARNING: translation string unused: localkey
 WARNING: translation string unused: localkeyfile
 WARNING: translation string unused: log enabled
@@ -398,6 +405,7 @@ WARNING: translation string unused: log level
 WARNING: translation string unused: log var messages
 WARNING: translation string unused: log view
 WARNING: translation string unused: log viewer
+WARNING: translation string unused: log-options
 WARNING: translation string unused: logging
 WARNING: translation string unused: loosedirectorychecking
 WARNING: translation string unused: ls_dhcpd
@@ -432,6 +440,7 @@ WARNING: translation string unused: meaning
 WARNING: translation string unused: memory usage per
 WARNING: translation string unused: messages logging
 WARNING: translation string unused: min size
+WARNING: translation string unused: misc-options
 WARNING: translation string unused: missing dat
 WARNING: translation string unused: missing gz
 WARNING: translation string unused: modem on com1
@@ -515,6 +524,10 @@ WARNING: translation string unused: ovpn config
 WARNING: translation string unused: ovpn device
 WARNING: translation string unused: ovpn dl
 WARNING: translation string unused: ovpn log
+WARNING: translation string unused: ovpn on blue
+WARNING: translation string unused: ovpn on orange
+WARNING: translation string unused: ovpn on red
+WARNING: translation string unused: ovpn server status
 WARNING: translation string unused: ovpn_fastio
 WARNING: translation string unused: ovpn_fragment
 WARNING: translation string unused: ovpn_mssfix
@@ -586,6 +599,7 @@ WARNING: translation string unused: reset shares
 WARNING: translation string unused: resetglobals
 WARNING: translation string unused: resetpolicy
 WARNING: translation string unused: resetshares
+WARNING: translation string unused: restart ovpn server
 WARNING: translation string unused: restore hardware settings
 WARNING: translation string unused: restore settings
 WARNING: translation string unused: root
@@ -661,6 +675,8 @@ WARNING: translation string unused: ssport forwarding
 WARNING: translation string unused: ssproxy graphs
 WARNING: translation string unused: sssystem status
 WARNING: translation string unused: sstraffic graphs
+WARNING: translation string unused: start ovpn server
+WARNING: translation string unused: stop ovpn server
 WARNING: translation string unused: subject test
 WARNING: translation string unused: subject warn
 WARNING: translation string unused: subnet
@@ -805,6 +821,11 @@ WARNING: translation string unused: xtaccess bad transfert
 WARNING: translation string unused: year-graph
 WARNING: translation string unused: yearly firewallhits
 WARNING: untranslated string: 24 hours = 24 Hours
+WARNING: untranslated string: AES-128-CBC = AES - CBC Mode - 128 Bit
+WARNING: untranslated string: AES-128-GCM = AES - GCM Mode - 128 Bit
+WARNING: untranslated string: AES-256-CBC = AES - CBC Mode - 256 Bit
+WARNING: untranslated string: AES-256-GCM = AES - GCM Mode - 256 Bit
+WARNING: untranslated string: CHACHA20-POLY1305 = ChaCha20-Poly1305
 WARNING: untranslated string: Captive = Captive Portal
 WARNING: untranslated string: Captive ACTIVATE = unknown string
 WARNING: untranslated string: Captive GAIN ACCESS = GAIN ACCESS
@@ -843,6 +864,7 @@ WARNING: untranslated string: ConnSched dial = Connect
 WARNING: untranslated string: ConnSched hangup = Disconnect
 WARNING: untranslated string: ConnSched reboot = Reboot
 WARNING: untranslated string: ConnSched shutdown = Shutdown
+WARNING: untranslated string: Disabled = Disabled
 WARNING: untranslated string: MB read = MB read
 WARNING: untranslated string: MB written = MB written
 WARNING: untranslated string: MTU settings = MTU settings:
@@ -882,7 +904,6 @@ WARNING: untranslated string: aliases default interface = - Default Interface -
 WARNING: untranslated string: allowed subnets = Allowed Subnets
 WARNING: untranslated string: asn lookup failed = AS lookup failed
 WARNING: untranslated string: atm device = Device:
-WARNING: untranslated string: attention = ATTENTION
 WARNING: untranslated string: autonomous system = Autonomous System
 WARNING: untranslated string: available = available
 WARNING: untranslated string: bit = bit
@@ -923,22 +944,18 @@ WARNING: untranslated string: ccd err isipsecrw = The given subnet address is al
 WARNING: untranslated string: ccd err isovpnn2n = The subnet address is already in use for an OpenVPN net-to-net connection.
 WARNING: untranslated string: ccd err isovpnnet = The subnet address is already in use for the OpenVPN server.
 WARNING: untranslated string: ccd err issubnet = Subnet address already in use.
-WARNING: untranslated string: ccd err name = Please choose a name.
 WARNING: untranslated string: ccd err nameexist = Name already exists.
 WARNING: untranslated string: ccd err netadrexist = Network already exists.
 WARNING: untranslated string: ccd err orange = This is the ORANGE subnet.
 WARNING: untranslated string: ccd err red = This is the RED subnet.
 WARNING: untranslated string: ccd err routeovpn = Already used by OpenVPN server.
 WARNING: untranslated string: ccd err routeovpn2 = Already pushed from OpenVPN server.
-WARNING: untranslated string: ccd hint = On this page you are able to define static networks from which the roadwarrior clients can get fixed IP address assignments.
 WARNING: untranslated string: ccd invalid = Invalid.
 WARNING: untranslated string: ccd iroute = IPFire has access to these networks on the client's site
 WARNING: untranslated string: ccd iroute2 = Client has access to these networks on IPFire's site
-WARNING: untranslated string: ccd iroutehint = Attention! If you change these settings, you have to restart the OpenVPN server that the changes take effect!
 WARNING: untranslated string: ccd modify = Change network
 WARNING: untranslated string: ccd name = Name
 WARNING: untranslated string: ccd net = Static IP address pools
-WARNING: untranslated string: ccd noaddnet = You can only add new static networks when OpenVPN server is stopped.
 WARNING: untranslated string: ccd none = None
 WARNING: untranslated string: ccd routes = Routing:
 WARNING: untranslated string: ccd subnet = Subnet
@@ -951,8 +968,6 @@ WARNING: untranslated string: countries = Countries
 WARNING: untranslated string: country codes and flags = Country Codes and Flags:
 WARNING: untranslated string: countrycode = Code
 WARNING: untranslated string: cpu frequency = CPU frequency
-WARNING: untranslated string: crypto error = Cryptographic error
-WARNING: untranslated string: crypto warning = Cryptographic warning
 WARNING: untranslated string: dangerous = Dangerous
 WARNING: untranslated string: data transfer = Data Transfer
 WARNING: untranslated string: dead peer detection = Dead Peer Detection
@@ -960,7 +975,6 @@ WARNING: untranslated string: default = Default
 WARNING: untranslated string: default IP address = Default IP Address
 WARNING: untranslated string: desired = Desired
 WARNING: untranslated string: details = Details
-WARNING: untranslated string: dh = Diffie-Hellman-Parameter
 WARNING: untranslated string: dhcp deny known clients: = Deny known clients:
 WARNING: untranslated string: dhcp dns enable update = Enable DNS Update (RFC2136):
 WARNING: untranslated string: dhcp dns key name = Key Name
@@ -972,7 +986,6 @@ WARNING: untranslated string: dhcp make fixed lease = Add to fix leases
 WARNING: untranslated string: dhcp valid range required when deny known clients checked = Valid range required when "Deny known clients:" is checked
 WARNING: untranslated string: disable = Disable
 WARNING: untranslated string: disconnected = Disconnected
-WARNING: untranslated string: dl client arch insecure = Download insecure Client Package (zip)
 WARNING: untranslated string: dnat address = Firewall Interface
 WARNING: untranslated string: dns check servers = Check DNS Servers
 WARNING: untranslated string: dns configuration = DNS Configuration
@@ -1160,7 +1173,6 @@ WARNING: untranslated string: fwdfw wd_sun = Sun
 WARNING: untranslated string: fwdfw wd_thu = Thu
 WARNING: untranslated string: fwdfw wd_tue = Tue
 WARNING: untranslated string: fwdfw wd_wed = Wed
-WARNING: untranslated string: fwhost OpenVPN N-2-N = OpenVPN Net-to-Net
 WARNING: untranslated string: fwhost addgrp = Add new network/host group
 WARNING: untranslated string: fwhost addgrpname = Group name:
 WARNING: untranslated string: fwhost addhost = Add new host
@@ -1451,22 +1463,31 @@ WARNING: untranslated string: otp qrcode = OTP QRCode
 WARNING: untranslated string: outgoing compression in bytes per second = Outgoing compression
 WARNING: untranslated string: outgoing firewall access = Outgoing Firewall Access
 WARNING: untranslated string: outgoing overhead in bytes per second = Outgoing Overhead
-WARNING: untranslated string: ovpn add conf = Additional configuration
+WARNING: untranslated string: ovpn ciphers = Ciphers
 WARNING: untranslated string: ovpn connection name = Connection Name
-WARNING: untranslated string: ovpn crypt options = Cryptographic options
-WARNING: untranslated string: ovpn errmsg green already pushed = Route for green network is always set
-WARNING: untranslated string: ovpn errmsg invalid ip or mask = Invalid network-address or subnetmask
-WARNING: untranslated string: ovpn error md5 = You host certificate uses MD5 for the signature which is not accepted anymore. <br>Please update to the latest IPFire version and generate a new root and host certificate.</br><br>All OpenVPN clients needs then to be renewed!</br>
+WARNING: untranslated string: ovpn crypto settings = Cryptographic Settings
+WARNING: untranslated string: ovpn dhcp settings = DHCP Settings
+WARNING: untranslated string: ovpn dynamic client subnet = Dynamic Client Subnet
+WARNING: untranslated string: ovpn errmsg invalid route = Invalid route
+WARNING: untranslated string: ovpn fallback cipher = Fallback Cipher
+WARNING: untranslated string: ovpn fallback cipher help = This cipher is being used by clients that do not support cipher negotiation.
+WARNING: untranslated string: ovpn fqdn = FQDN
 WARNING: untranslated string: ovpn ha = Hash algorithm
 WARNING: untranslated string: ovpn mgmt in root range = A port number of 1024 or higher is required.
+WARNING: untranslated string: ovpn misc settings = Miscellaneous Settings
+WARNING: untranslated string: ovpn no cipher selected = No cipher selected
 WARNING: untranslated string: ovpn no connections = No active OpenVPN connections
 WARNING: untranslated string: ovpn port in root range = A port number of 1024 or higher is required.
+WARNING: untranslated string: ovpn protocol settings = Protocol Settings
+WARNING: untranslated string: ovpn push default route = Push Default Route
 WARNING: untranslated string: ovpn roadwarrior server = OpenVPN Roadwarrior Server
-WARNING: untranslated string: ovpn routes push = Routes (one per line) e.g. 192.168.10.0/255.255.255.0 192.168.20.0/24
-WARNING: untranslated string: ovpn routes push options = Route push options
+WARNING: untranslated string: ovpn roadwarrior settings = Roadwarrior Settings
+WARNING: untranslated string: ovpn routes push = Custom Routes
+WARNING: untranslated string: ovpn routing settings = Routing Settings
 WARNING: untranslated string: ovpn rw connection log = OpenVPN Roadwarrior Connections Log
 WARNING: untranslated string: ovpn tls auth = TLS Channel Protection:
-WARNING: untranslated string: ovpn warning rfc3280 = Your host certificate is not RFC3280 compliant. <br>Please update to the latest IPFire version and generate as soon as possible a new root and host certificate.</br><br>All OpenVPN clients needs then to be renewed!</br>
+WARNING: untranslated string: ovpn transport protocol = Transport Protocol
+WARNING: untranslated string: ovpn unsupported cipher selected = Unknown cipher selected
 WARNING: untranslated string: pak update = Update
 WARNING: untranslated string: pakfire already busy = Pakfire is already performing a task. Please try again later.
 WARNING: untranslated string: pakfire finished = Pakfire has finished! Returning...
@@ -1514,6 +1535,8 @@ WARNING: untranslated string: routing = Routing
 WARNING: untranslated string: routing config added = unknown string
 WARNING: untranslated string: routing config changed = unknown string
 WARNING: untranslated string: routing table = unknown string
+WARNING: untranslated string: rss = RSS
+WARNING: untranslated string: rss long = Resident Set Size
 WARNING: untranslated string: samba join a domain = Join a domain
 WARNING: untranslated string: samba join domain = Join domain
 WARNING: untranslated string: samba server role member = Domain Member
@@ -1522,9 +1545,7 @@ WARNING: untranslated string: scanned = Scanned
 WARNING: untranslated string: search = Search
 WARNING: untranslated string: secret = Secret
 WARNING: untranslated string: sent = Sent
-WARNING: untranslated string: server restart = You are not able to save any changes while the OpenVPN server is running.
 WARNING: untranslated string: service boot setting unavailable = No valid runlevel symlink was found for the initscript of this service.
-WARNING: untranslated string: show dh = Show Diffie-Hellman parameters
 WARNING: untranslated string: show otp qrcode = Show OTP QRCode
 WARNING: untranslated string: show tls-auth key = Show tls-auth key
 WARNING: untranslated string: smb daemon = SMB Daemon
@@ -1579,7 +1600,6 @@ WARNING: untranslated string: tor common settings = Common Settings
 WARNING: untranslated string: tor configuration = Tor Configuration
 WARNING: untranslated string: tor connected relays = Connected relays
 WARNING: untranslated string: tor contact info = Contact Info
-WARNING: untranslated string: tor daemon = Daemon
 WARNING: untranslated string: tor directory port = Directory port
 WARNING: untranslated string: tor enabled = Enable Tor
 WARNING: untranslated string: tor errmsg invalid accounting limit = Invalid accounting limit
diff --git a/doc/language_issues.ru b/doc/language_issues.ru
index 0328cee363..b0ad37a520 100644
--- a/doc/language_issues.ru
+++ b/doc/language_issues.ru
@@ -6,6 +6,7 @@ WARNING: translation string unused: Existing Files
 WARNING: translation string unused: HDD temperature
 WARNING: translation string unused: Level7 rule
 WARNING: translation string unused: Local VPN IP
+WARNING: translation string unused: OVPN
 WARNING: translation string unused: Pages
 WARNING: translation string unused: Ping
 WARNING: translation string unused: Queuelenght
@@ -203,6 +204,7 @@ WARNING: translation string unused: dhcp fixed lease help1
 WARNING: translation string unused: dhcp mode
 WARNING: translation string unused: dhcp server disabled on blue interface
 WARNING: translation string unused: dhcp server enabled on blue interface
+WARNING: translation string unused: dhcp-options
 WARNING: translation string unused: dial user password
 WARNING: translation string unused: dial user password has been changed
 WARNING: translation string unused: dialup settings
@@ -360,6 +362,9 @@ WARNING: translation string unused: intrusion detection system2
 WARNING: translation string unused: invalid cache size
 WARNING: translation string unused: invalid date entered
 WARNING: translation string unused: invalid downlink speed
+WARNING: translation string unused: invalid input for keepalive 1
+WARNING: translation string unused: invalid input for keepalive 1:2
+WARNING: translation string unused: invalid input for keepalive 2
 WARNING: translation string unused: invalid input for oink code
 WARNING: translation string unused: invalid loaded file
 WARNING: translation string unused: invalid md5sum
@@ -371,6 +376,7 @@ WARNING: translation string unused: invalid users
 WARNING: translation string unused: invert
 WARNING: translation string unused: ip address in use
 WARNING: translation string unused: ipfire side
+WARNING: translation string unused: ipfire side is invalid
 WARNING: translation string unused: iptable rules
 WARNING: translation string unused: javascript menu error1
 WARNING: translation string unused: javascript menu error2
@@ -387,6 +393,7 @@ WARNING: translation string unused: load printer
 WARNING: translation string unused: loaded modules
 WARNING: translation string unused: local hard disk
 WARNING: translation string unused: local master
+WARNING: translation string unused: local vpn hostname/ip
 WARNING: translation string unused: localkey
 WARNING: translation string unused: localkeyfile
 WARNING: translation string unused: log enabled
@@ -394,6 +401,7 @@ WARNING: translation string unused: log level
 WARNING: translation string unused: log var messages
 WARNING: translation string unused: log view
 WARNING: translation string unused: log viewer
+WARNING: translation string unused: log-options
 WARNING: translation string unused: logging
 WARNING: translation string unused: loosedirectorychecking
 WARNING: translation string unused: ls_dhcpd
@@ -428,6 +436,7 @@ WARNING: translation string unused: meaning
 WARNING: translation string unused: memory usage per
 WARNING: translation string unused: messages logging
 WARNING: translation string unused: min size
+WARNING: translation string unused: misc-options
 WARNING: translation string unused: missing dat
 WARNING: translation string unused: missing gz
 WARNING: translation string unused: modem on com1
@@ -509,7 +518,14 @@ WARNING: translation string unused: override mtu
 WARNING: translation string unused: ovpn config
 WARNING: translation string unused: ovpn device
 WARNING: translation string unused: ovpn dl
+WARNING: translation string unused: ovpn errmsg green already pushed
+WARNING: translation string unused: ovpn errmsg invalid ip or mask
 WARNING: translation string unused: ovpn log
+WARNING: translation string unused: ovpn on blue
+WARNING: translation string unused: ovpn on orange
+WARNING: translation string unused: ovpn on red
+WARNING: translation string unused: ovpn routes push options
+WARNING: translation string unused: ovpn server status
 WARNING: translation string unused: ovpn_fastio
 WARNING: translation string unused: ovpn_fragment
 WARNING: translation string unused: ovpn_mssfix
@@ -581,6 +597,7 @@ WARNING: translation string unused: reset shares
 WARNING: translation string unused: resetglobals
 WARNING: translation string unused: resetpolicy
 WARNING: translation string unused: resetshares
+WARNING: translation string unused: restart ovpn server
 WARNING: translation string unused: restore hardware settings
 WARNING: translation string unused: restore settings
 WARNING: translation string unused: root
@@ -656,6 +673,8 @@ WARNING: translation string unused: ssport forwarding
 WARNING: translation string unused: ssproxy graphs
 WARNING: translation string unused: sssystem status
 WARNING: translation string unused: sstraffic graphs
+WARNING: translation string unused: start ovpn server
+WARNING: translation string unused: stop ovpn server
 WARNING: translation string unused: subject test
 WARNING: translation string unused: subject warn
 WARNING: translation string unused: subnet
@@ -798,7 +817,12 @@ WARNING: translation string unused: xtaccess all error
 WARNING: translation string unused: xtaccess bad transfert
 WARNING: translation string unused: yearly firewallhits
 WARNING: untranslated string: 24 hours = 24 Hours
+WARNING: untranslated string: AES-128-CBC = AES - CBC Mode - 128 Bit
+WARNING: untranslated string: AES-128-GCM = AES - GCM Mode - 128 Bit
+WARNING: untranslated string: AES-256-CBC = AES - CBC Mode - 256 Bit
+WARNING: untranslated string: AES-256-GCM = AES - GCM Mode - 256 Bit
 WARNING: untranslated string: Add a route = Add a route
+WARNING: untranslated string: CHACHA20-POLY1305 = ChaCha20-Poly1305
 WARNING: untranslated string: Captive = Captive Portal
 WARNING: untranslated string: Captive ACTIVATE = unknown string
 WARNING: untranslated string: Captive GAIN ACCESS = GAIN ACCESS
@@ -837,6 +861,7 @@ WARNING: untranslated string: ConnSched dial = Connect
 WARNING: untranslated string: ConnSched hangup = Disconnect
 WARNING: untranslated string: ConnSched reboot = Reboot
 WARNING: untranslated string: ConnSched shutdown = Shutdown
+WARNING: untranslated string: Disabled = Disabled
 WARNING: untranslated string: Edit an existing route = Edit an existing route
 WARNING: untranslated string: MB read = MB read
 WARNING: untranslated string: MB written = MB written
@@ -877,7 +902,6 @@ WARNING: untranslated string: aliases default interface = - Default Interface -
 WARNING: untranslated string: allowed subnets = Allowed Subnets
 WARNING: untranslated string: asn lookup failed = AS lookup failed
 WARNING: untranslated string: atm device = Device:
-WARNING: untranslated string: attention = ATTENTION
 WARNING: untranslated string: autonomous system = Autonomous System
 WARNING: untranslated string: available = available
 WARNING: untranslated string: bit = bit
@@ -918,22 +942,18 @@ WARNING: untranslated string: ccd err isipsecrw = The given subnet address is al
 WARNING: untranslated string: ccd err isovpnn2n = The subnet address is already in use for an OpenVPN net-to-net connection.
 WARNING: untranslated string: ccd err isovpnnet = The subnet address is already in use for the OpenVPN server.
 WARNING: untranslated string: ccd err issubnet = Subnet address already in use.
-WARNING: untranslated string: ccd err name = Please choose a name.
 WARNING: untranslated string: ccd err nameexist = Name already exists.
 WARNING: untranslated string: ccd err netadrexist = Network already exists.
 WARNING: untranslated string: ccd err orange = This is the ORANGE subnet.
 WARNING: untranslated string: ccd err red = This is the RED subnet.
 WARNING: untranslated string: ccd err routeovpn = Already used by OpenVPN server.
 WARNING: untranslated string: ccd err routeovpn2 = Already pushed from OpenVPN server.
-WARNING: untranslated string: ccd hint = On this page you are able to define static networks from which the roadwarrior clients can get fixed IP address assignments.
 WARNING: untranslated string: ccd invalid = Invalid.
 WARNING: untranslated string: ccd iroute = IPFire has access to these networks on the client's site
 WARNING: untranslated string: ccd iroute2 = Client has access to these networks on IPFire's site
-WARNING: untranslated string: ccd iroutehint = Attention! If you change these settings, you have to restart the OpenVPN server that the changes take effect!
 WARNING: untranslated string: ccd modify = Change network
 WARNING: untranslated string: ccd name = Name
 WARNING: untranslated string: ccd net = Static IP address pools
-WARNING: untranslated string: ccd noaddnet = You can only add new static networks when OpenVPN server is stopped.
 WARNING: untranslated string: ccd none = None
 WARNING: untranslated string: ccd routes = Routing:
 WARNING: untranslated string: ccd subnet = Subnet
@@ -946,8 +966,6 @@ WARNING: untranslated string: countries = Countries
 WARNING: untranslated string: country codes and flags = Country Codes and Flags:
 WARNING: untranslated string: countrycode = Code
 WARNING: untranslated string: cpu frequency = CPU frequency
-WARNING: untranslated string: crypto error = Cryptographic error
-WARNING: untranslated string: crypto warning = Cryptographic warning
 WARNING: untranslated string: dangerous = Dangerous
 WARNING: untranslated string: data transfer = Data Transfer
 WARNING: untranslated string: dead peer detection = Dead Peer Detection
@@ -955,7 +973,6 @@ WARNING: untranslated string: default = Default
 WARNING: untranslated string: default IP address = Default IP Address
 WARNING: untranslated string: desired = Desired
 WARNING: untranslated string: details = Details
-WARNING: untranslated string: dh = Diffie-Hellman-Parameter
 WARNING: untranslated string: dhcp deny known clients: = Deny known clients:
 WARNING: untranslated string: dhcp dns enable update = Enable DNS Update (RFC2136):
 WARNING: untranslated string: dhcp dns key name = Key Name
@@ -967,7 +984,6 @@ WARNING: untranslated string: dhcp make fixed lease = Add to fix leases
 WARNING: untranslated string: dhcp valid range required when deny known clients checked = Valid range required when "Deny known clients:" is checked
 WARNING: untranslated string: disable = Disable
 WARNING: untranslated string: disconnected = Disconnected
-WARNING: untranslated string: dl client arch insecure = Download insecure Client Package (zip)
 WARNING: untranslated string: dnat address = Firewall Interface
 WARNING: untranslated string: dns check servers = Check DNS Servers
 WARNING: untranslated string: dns configuration = DNS Configuration
@@ -1155,7 +1171,6 @@ WARNING: untranslated string: fwdfw wd_sun = Sun
 WARNING: untranslated string: fwdfw wd_thu = Thu
 WARNING: untranslated string: fwdfw wd_tue = Tue
 WARNING: untranslated string: fwdfw wd_wed = Wed
-WARNING: untranslated string: fwhost OpenVPN N-2-N = OpenVPN Net-to-Net
 WARNING: untranslated string: fwhost addgrp = Add new network/host group
 WARNING: untranslated string: fwhost addgrpname = Group name:
 WARNING: untranslated string: fwhost addhost = Add new host
@@ -1448,18 +1463,30 @@ WARNING: untranslated string: outgoing compression in bytes per second = Outgoin
 WARNING: untranslated string: outgoing firewall access = Outgoing Firewall Access
 WARNING: untranslated string: outgoing overhead in bytes per second = Outgoing Overhead
 WARNING: untranslated string: outgoing traffic in bytes per second = Outgoing Traffic
-WARNING: untranslated string: ovpn add conf = Additional configuration
+WARNING: untranslated string: ovpn ciphers = Ciphers
 WARNING: untranslated string: ovpn connection name = Connection Name
-WARNING: untranslated string: ovpn crypt options = Cryptographic options
-WARNING: untranslated string: ovpn error md5 = You host certificate uses MD5 for the signature which is not accepted anymore. <br>Please update to the latest IPFire version and generate a new root and host certificate.</br><br>All OpenVPN clients needs then to be renewed!</br>
+WARNING: untranslated string: ovpn crypto settings = Cryptographic Settings
+WARNING: untranslated string: ovpn dhcp settings = DHCP Settings
+WARNING: untranslated string: ovpn dynamic client subnet = Dynamic Client Subnet
+WARNING: untranslated string: ovpn errmsg invalid route = Invalid route
+WARNING: untranslated string: ovpn fallback cipher = Fallback Cipher
+WARNING: untranslated string: ovpn fallback cipher help = This cipher is being used by clients that do not support cipher negotiation.
+WARNING: untranslated string: ovpn fqdn = FQDN
 WARNING: untranslated string: ovpn ha = Hash algorithm
 WARNING: untranslated string: ovpn mgmt in root range = A port number of 1024 or higher is required.
+WARNING: untranslated string: ovpn misc settings = Miscellaneous Settings
+WARNING: untranslated string: ovpn no cipher selected = No cipher selected
 WARNING: untranslated string: ovpn no connections = No active OpenVPN connections
 WARNING: untranslated string: ovpn port in root range = A port number of 1024 or higher is required.
+WARNING: untranslated string: ovpn protocol settings = Protocol Settings
+WARNING: untranslated string: ovpn push default route = Push Default Route
 WARNING: untranslated string: ovpn roadwarrior server = OpenVPN Roadwarrior Server
+WARNING: untranslated string: ovpn roadwarrior settings = Roadwarrior Settings
+WARNING: untranslated string: ovpn routing settings = Routing Settings
 WARNING: untranslated string: ovpn rw connection log = OpenVPN Roadwarrior Connections Log
 WARNING: untranslated string: ovpn tls auth = TLS Channel Protection:
-WARNING: untranslated string: ovpn warning rfc3280 = Your host certificate is not RFC3280 compliant. <br>Please update to the latest IPFire version and generate as soon as possible a new root and host certificate.</br><br>All OpenVPN clients needs then to be renewed!</br>
+WARNING: untranslated string: ovpn transport protocol = Transport Protocol
+WARNING: untranslated string: ovpn unsupported cipher selected = Unknown cipher selected
 WARNING: untranslated string: pak update = Update
 WARNING: untranslated string: pakfire already busy = Pakfire is already performing a task. Please try again later.
 WARNING: untranslated string: pakfire finished = Pakfire has finished! Returning...
@@ -1507,6 +1534,8 @@ WARNING: untranslated string: routing = Routing
 WARNING: untranslated string: routing config added = unknown string
 WARNING: untranslated string: routing config changed = unknown string
 WARNING: untranslated string: routing table = unknown string
+WARNING: untranslated string: rss = RSS
+WARNING: untranslated string: rss long = Resident Set Size
 WARNING: untranslated string: samba join a domain = Join a domain
 WARNING: untranslated string: samba join domain = Join domain
 WARNING: untranslated string: samba server role member = Domain Member
@@ -1515,9 +1544,7 @@ WARNING: untranslated string: scanned = Scanned
 WARNING: untranslated string: search = Search
 WARNING: untranslated string: secret = Secret
 WARNING: untranslated string: sent = Sent
-WARNING: untranslated string: server restart = You are not able to save any changes while the OpenVPN server is running.
 WARNING: untranslated string: service boot setting unavailable = No valid runlevel symlink was found for the initscript of this service.
-WARNING: untranslated string: show dh = Show Diffie-Hellman parameters
 WARNING: untranslated string: show otp qrcode = Show OTP QRCode
 WARNING: untranslated string: show tls-auth key = Show tls-auth key
 WARNING: untranslated string: smb daemon = SMB Daemon
@@ -1572,7 +1599,6 @@ WARNING: untranslated string: tor common settings = Common Settings
 WARNING: untranslated string: tor configuration = Tor Configuration
 WARNING: untranslated string: tor connected relays = Connected relays
 WARNING: untranslated string: tor contact info = Contact Info
-WARNING: untranslated string: tor daemon = Daemon
 WARNING: untranslated string: tor directory port = Directory port
 WARNING: untranslated string: tor enabled = Enable Tor
 WARNING: untranslated string: tor errmsg invalid accounting limit = Invalid accounting limit
diff --git a/doc/language_issues.tr b/doc/language_issues.tr
index d5c3237670..74e60c0f08 100644
--- a/doc/language_issues.tr
+++ b/doc/language_issues.tr
@@ -27,6 +27,7 @@ WARNING: translation string unused: Existing Files
 WARNING: translation string unused: HDD temperature
 WARNING: translation string unused: Level7 rule
 WARNING: translation string unused: Local VPN IP
+WARNING: translation string unused: OVPN
 WARNING: translation string unused: Pages
 WARNING: translation string unused: Ping
 WARNING: translation string unused: Queuelenght
@@ -126,6 +127,7 @@ WARNING: translation string unused: apply
 WARNING: translation string unused: archive not exist
 WARNING: translation string unused: artist
 WARNING: translation string unused: attemps
+WARNING: translation string unused: attention
 WARNING: translation string unused: avoid dod
 WARNING: translation string unused: backup archive
 WARNING: translation string unused: backup clear archive
@@ -169,7 +171,11 @@ WARNING: translation string unused: cannot enable both nat traversal and compres
 WARNING: translation string unused: cant enable xtaccess
 WARNING: translation string unused: capsinactive
 WARNING: translation string unused: ccd err iroute
+WARNING: translation string unused: ccd err name
 WARNING: translation string unused: ccd err netadr
+WARNING: translation string unused: ccd hint
+WARNING: translation string unused: ccd iroutehint
+WARNING: translation string unused: ccd noaddnet
 WARNING: translation string unused: cfg restart
 WARNING: translation string unused: change share
 WARNING: translation string unused: check for net traffic update
@@ -236,6 +242,7 @@ WARNING: translation string unused: dhcp fixed lease help1
 WARNING: translation string unused: dhcp mode
 WARNING: translation string unused: dhcp server disabled on blue interface
 WARNING: translation string unused: dhcp server enabled on blue interface
+WARNING: translation string unused: dhcp-options
 WARNING: translation string unused: dial user password
 WARNING: translation string unused: dial user password has been changed
 WARNING: translation string unused: dialup settings
@@ -247,6 +254,7 @@ WARNING: translation string unused: disk access
 WARNING: translation string unused: display charset
 WARNING: translation string unused: display traffic at home
 WARNING: translation string unused: display webinterface effects
+WARNING: translation string unused: dl client arch insecure
 WARNING: translation string unused: dmz pinhole configuration
 WARNING: translation string unused: dmz pinhole rule added
 WARNING: translation string unused: dmz pinhole rule removed
@@ -370,6 +378,7 @@ WARNING: translation string unused: fwhost Custom Host
 WARNING: translation string unused: fwhost Custom Network
 WARNING: translation string unused: fwhost IpSec Host
 WARNING: translation string unused: fwhost IpSec Network
+WARNING: translation string unused: fwhost OpenVPN N-2-N
 WARNING: translation string unused: fwhost OpenVPN static host
 WARNING: translation string unused: fwhost OpenVPN static network
 WARNING: translation string unused: fwhost Standard Network
@@ -449,6 +458,9 @@ WARNING: translation string unused: intrusion detection system2
 WARNING: translation string unused: invalid cache size
 WARNING: translation string unused: invalid date entered
 WARNING: translation string unused: invalid downlink speed
+WARNING: translation string unused: invalid input for keepalive 1
+WARNING: translation string unused: invalid input for keepalive 1:2
+WARNING: translation string unused: invalid input for keepalive 2
 WARNING: translation string unused: invalid input for oink code
 WARNING: translation string unused: invalid loaded file
 WARNING: translation string unused: invalid md5sum
@@ -460,6 +472,7 @@ WARNING: translation string unused: invalid users
 WARNING: translation string unused: invert
 WARNING: translation string unused: ip address in use
 WARNING: translation string unused: ipfire side
+WARNING: translation string unused: ipfire side is invalid
 WARNING: translation string unused: ipsec no connections
 WARNING: translation string unused: iptable rules
 WARNING: translation string unused: javascript menu error1
@@ -477,6 +490,7 @@ WARNING: translation string unused: load printer
 WARNING: translation string unused: loaded modules
 WARNING: translation string unused: local hard disk
 WARNING: translation string unused: local master
+WARNING: translation string unused: local vpn hostname/ip
 WARNING: translation string unused: localkey
 WARNING: translation string unused: localkeyfile
 WARNING: translation string unused: locationblock country code
@@ -487,6 +501,7 @@ WARNING: translation string unused: log level
 WARNING: translation string unused: log var messages
 WARNING: translation string unused: log view
 WARNING: translation string unused: log viewer
+WARNING: translation string unused: log-options
 WARNING: translation string unused: logging
 WARNING: translation string unused: loosedirectorychecking
 WARNING: translation string unused: ls_dhcpd
@@ -522,6 +537,7 @@ WARNING: translation string unused: meaning
 WARNING: translation string unused: memory usage per
 WARNING: translation string unused: messages logging
 WARNING: translation string unused: min size
+WARNING: translation string unused: misc-options
 WARNING: translation string unused: missing dat
 WARNING: translation string unused: missing gz
 WARNING: translation string unused: modem on com1
@@ -606,10 +622,14 @@ WARNING: translation string unused: outgoing firewall reset
 WARNING: translation string unused: outgoing firewall view group
 WARNING: translation string unused: outgoing firewall warning
 WARNING: translation string unused: override mtu
+WARNING: translation string unused: ovpn add conf
 WARNING: translation string unused: ovpn config
+WARNING: translation string unused: ovpn crypt options
 WARNING: translation string unused: ovpn device
 WARNING: translation string unused: ovpn dl
 WARNING: translation string unused: ovpn engines
+WARNING: translation string unused: ovpn errmsg green already pushed
+WARNING: translation string unused: ovpn errmsg invalid ip or mask
 WARNING: translation string unused: ovpn generating the root and host certificates
 WARNING: translation string unused: ovpn hmac
 WARNING: translation string unused: ovpn log
@@ -620,7 +640,12 @@ WARNING: translation string unused: ovpn mtu-disc no
 WARNING: translation string unused: ovpn mtu-disc off
 WARNING: translation string unused: ovpn mtu-disc with mssfix or fragment
 WARNING: translation string unused: ovpn mtu-disc yes
+WARNING: translation string unused: ovpn on blue
+WARNING: translation string unused: ovpn on orange
+WARNING: translation string unused: ovpn on red
 WARNING: translation string unused: ovpn reneg sec
+WARNING: translation string unused: ovpn routes push options
+WARNING: translation string unused: ovpn server status
 WARNING: translation string unused: ovpn_fastio
 WARNING: translation string unused: ovpn_mssfix
 WARNING: translation string unused: ovpn_mtudisc
@@ -691,6 +716,7 @@ WARNING: translation string unused: reset shares
 WARNING: translation string unused: resetglobals
 WARNING: translation string unused: resetpolicy
 WARNING: translation string unused: resetshares
+WARNING: translation string unused: restart ovpn server
 WARNING: translation string unused: restore hardware settings
 WARNING: translation string unused: restore settings
 WARNING: translation string unused: root
@@ -713,6 +739,7 @@ WARNING: translation string unused: selecttraffic
 WARNING: translation string unused: send email notification
 WARNING: translation string unused: send test mail
 WARNING: translation string unused: server reserved
+WARNING: translation string unused: server restart
 WARNING: translation string unused: server string
 WARNING: translation string unused: service added
 WARNING: translation string unused: service removed
@@ -766,6 +793,8 @@ WARNING: translation string unused: ssport forwarding
 WARNING: translation string unused: ssproxy graphs
 WARNING: translation string unused: sssystem status
 WARNING: translation string unused: sstraffic graphs
+WARNING: translation string unused: start ovpn server
+WARNING: translation string unused: stop ovpn server
 WARNING: translation string unused: subject test
 WARNING: translation string unused: subject warn
 WARNING: translation string unused: subnet
@@ -802,6 +831,7 @@ WARNING: translation string unused: tor accounting period daily
 WARNING: translation string unused: tor accounting period monthly
 WARNING: translation string unused: tor accounting period weekly
 WARNING: translation string unused: tor bridge enabled
+WARNING: translation string unused: tor daemon
 WARNING: translation string unused: tor errmsg invalid node id
 WARNING: translation string unused: tor exit country
 WARNING: translation string unused: traffic back
@@ -922,8 +952,14 @@ WARNING: translation string unused: xtaccess all error
 WARNING: translation string unused: xtaccess bad transfert
 WARNING: translation string unused: year-graph
 WARNING: translation string unused: yearly firewallhits
+WARNING: untranslated string: AES-128-CBC = AES - CBC Mode - 128 Bit
+WARNING: untranslated string: AES-128-GCM = AES - GCM Mode - 128 Bit
+WARNING: untranslated string: AES-256-CBC = AES - CBC Mode - 256 Bit
+WARNING: untranslated string: AES-256-GCM = AES - GCM Mode - 256 Bit
+WARNING: untranslated string: CHACHA20-POLY1305 = ChaCha20-Poly1305
 WARNING: untranslated string: Captive clients = unknown string
 WARNING: untranslated string: Captive delete logo = Delete Logo
+WARNING: untranslated string: Disabled = Disabled
 WARNING: untranslated string: access point name = Access Point Name
 WARNING: untranslated string: access point name is invalid = Access Point Name is invalid
 WARNING: untranslated string: access point name is required = Access Point Name is required
@@ -968,13 +1004,10 @@ WARNING: untranslated string: cake profile raw 0 = Raw (no overhead compensation
 WARNING: untranslated string: configuration file = Configuration File
 WARNING: untranslated string: core update = Core-Update
 WARNING: untranslated string: cpu frequency = CPU frequency
-WARNING: untranslated string: crypto error = Cryptographic error
-WARNING: untranslated string: crypto warning = Cryptographic warning
 WARNING: untranslated string: dangerous = Dangerous
 WARNING: untranslated string: data transfer = Data Transfer
 WARNING: untranslated string: default IP address = Default IP Address
 WARNING: untranslated string: desired = Desired
-WARNING: untranslated string: dh = Diffie-Hellman-Parameter
 WARNING: untranslated string: dhcp deny known clients: = Deny known clients:
 WARNING: untranslated string: dhcp fixed ip address in dynamic range = Fixed IP Address in dynamic range
 WARNING: untranslated string: dhcp make fixed lease = Add to fix leases
@@ -1180,12 +1213,26 @@ WARNING: untranslated string: openvpn cert expires soon = Expires Soon
 WARNING: untranslated string: openvpn cert has expired = Expired
 WARNING: untranslated string: optional = Optional
 WARNING: untranslated string: otp qrcode = OTP QRCode
+WARNING: untranslated string: ovpn ciphers = Ciphers
 WARNING: untranslated string: ovpn connection name = Connection Name
-WARNING: untranslated string: ovpn error md5 = You host certificate uses MD5 for the signature which is not accepted anymore. <br>Please update to the latest IPFire version and generate a new root and host certificate.</br><br>All OpenVPN clients needs then to be renewed!</br>
+WARNING: untranslated string: ovpn crypto settings = Cryptographic Settings
+WARNING: untranslated string: ovpn dhcp settings = DHCP Settings
+WARNING: untranslated string: ovpn dynamic client subnet = Dynamic Client Subnet
+WARNING: untranslated string: ovpn errmsg invalid route = Invalid route
+WARNING: untranslated string: ovpn fallback cipher = Fallback Cipher
+WARNING: untranslated string: ovpn fallback cipher help = This cipher is being used by clients that do not support cipher negotiation.
+WARNING: untranslated string: ovpn fqdn = FQDN
+WARNING: untranslated string: ovpn misc settings = Miscellaneous Settings
+WARNING: untranslated string: ovpn no cipher selected = No cipher selected
+WARNING: untranslated string: ovpn protocol settings = Protocol Settings
+WARNING: untranslated string: ovpn push default route = Push Default Route
 WARNING: untranslated string: ovpn roadwarrior server = OpenVPN Roadwarrior Server
+WARNING: untranslated string: ovpn roadwarrior settings = Roadwarrior Settings
+WARNING: untranslated string: ovpn routing settings = Routing Settings
 WARNING: untranslated string: ovpn rw connection log = OpenVPN Roadwarrior Connections Log
 WARNING: untranslated string: ovpn tls auth = TLS Channel Protection:
-WARNING: untranslated string: ovpn warning rfc3280 = Your host certificate is not RFC3280 compliant. <br>Please update to the latest IPFire version and generate as soon as possible a new root and host certificate.</br><br>All OpenVPN clients needs then to be renewed!</br>
+WARNING: untranslated string: ovpn transport protocol = Transport Protocol
+WARNING: untranslated string: ovpn unsupported cipher selected = Unknown cipher selected
 WARNING: untranslated string: pak update = Update
 WARNING: untranslated string: pakfire already busy = Pakfire is already performing a task. Please try again later.
 WARNING: untranslated string: pakfire finished = Pakfire has finished! Returning...
@@ -1221,13 +1268,14 @@ WARNING: untranslated string: routing = Routing
 WARNING: untranslated string: routing config added = unknown string
 WARNING: untranslated string: routing config changed = unknown string
 WARNING: untranslated string: routing table = unknown string
+WARNING: untranslated string: rss = RSS
+WARNING: untranslated string: rss long = Resident Set Size
 WARNING: untranslated string: samba server role member = Domain Member
 WARNING: untranslated string: samba server role standalone = Standalone
 WARNING: untranslated string: scanned = Scanned
 WARNING: untranslated string: secret = Secret
 WARNING: untranslated string: sent = Sent
 WARNING: untranslated string: service boot setting unavailable = No valid runlevel symlink was found for the initscript of this service.
-WARNING: untranslated string: show dh = Show Diffie-Hellman parameters
 WARNING: untranslated string: show otp qrcode = Show OTP QRCode
 WARNING: untranslated string: smb daemon = SMB Daemon
 WARNING: untranslated string: smt disabled = Simultaneous Multi-Threading (SMT) is disabled
diff --git a/doc/language_issues.tw b/doc/language_issues.tw
index 92ef9269a8..d6f8cbf689 100644
--- a/doc/language_issues.tw
+++ b/doc/language_issues.tw
@@ -25,11 +25,11 @@ WARNING: translation string unused: Captive wrong ext
 WARNING: translation string unused: ConnSched scheduler
 WARNING: translation string unused: ConnSched select profile
 WARNING: translation string unused: Daily
-WARNING: translation string unused: Disabled
 WARNING: translation string unused: Existing Files
 WARNING: translation string unused: HDD temperature
 WARNING: translation string unused: Level7 rule
 WARNING: translation string unused: Local VPN IP
+WARNING: translation string unused: OVPN
 WARNING: translation string unused: Pages
 WARNING: translation string unused: Ping
 WARNING: translation string unused: Queuelenght
@@ -133,6 +133,7 @@ WARNING: translation string unused: apply
 WARNING: translation string unused: archive not exist
 WARNING: translation string unused: artist
 WARNING: translation string unused: attemps
+WARNING: translation string unused: attention
 WARNING: translation string unused: available updates
 WARNING: translation string unused: avoid dod
 WARNING: translation string unused: backup archive
@@ -178,7 +179,11 @@ WARNING: translation string unused: cannot enable both nat traversal and compres
 WARNING: translation string unused: cant enable xtaccess
 WARNING: translation string unused: capsinactive
 WARNING: translation string unused: ccd err iroute
+WARNING: translation string unused: ccd err name
 WARNING: translation string unused: ccd err netadr
+WARNING: translation string unused: ccd hint
+WARNING: translation string unused: ccd iroutehint
+WARNING: translation string unused: ccd noaddnet
 WARNING: translation string unused: cfg restart
 WARNING: translation string unused: change share
 WARNING: translation string unused: check for net traffic update
@@ -206,6 +211,8 @@ WARNING: translation string unused: cpu frequency per
 WARNING: translation string unused: cpu usage per
 WARNING: translation string unused: create mask
 WARNING: translation string unused: create new backup
+WARNING: translation string unused: crypto error
+WARNING: translation string unused: crypto warning
 WARNING: translation string unused: cryptographic settings
 WARNING: translation string unused: current media
 WARNING: translation string unused: current ovpn
@@ -239,6 +246,7 @@ WARNING: translation string unused: destination ip bad
 WARNING: translation string unused: destination ip or net
 WARNING: translation string unused: destination net
 WARNING: translation string unused: destination port overlaps
+WARNING: translation string unused: dh
 WARNING: translation string unused: dhcp base ip fixed lease
 WARNING: translation string unused: dhcp create fixed leases
 WARNING: translation string unused: dhcp fixed lease err1
@@ -246,6 +254,7 @@ WARNING: translation string unused: dhcp fixed lease help1
 WARNING: translation string unused: dhcp mode
 WARNING: translation string unused: dhcp server disabled on blue interface
 WARNING: translation string unused: dhcp server enabled on blue interface
+WARNING: translation string unused: dhcp-options
 WARNING: translation string unused: dial user password
 WARNING: translation string unused: dial user password has been changed
 WARNING: translation string unused: dialup settings
@@ -257,6 +266,7 @@ WARNING: translation string unused: disk access
 WARNING: translation string unused: display charset
 WARNING: translation string unused: display traffic at home
 WARNING: translation string unused: display webinterface effects
+WARNING: translation string unused: dl client arch insecure
 WARNING: translation string unused: dmz pinhole configuration
 WARNING: translation string unused: dmz pinhole rule added
 WARNING: translation string unused: dmz pinhole rule removed
@@ -384,6 +394,7 @@ WARNING: translation string unused: fwhost Custom Host
 WARNING: translation string unused: fwhost Custom Network
 WARNING: translation string unused: fwhost IpSec Host
 WARNING: translation string unused: fwhost IpSec Network
+WARNING: translation string unused: fwhost OpenVPN N-2-N
 WARNING: translation string unused: fwhost OpenVPN static host
 WARNING: translation string unused: fwhost OpenVPN static network
 WARNING: translation string unused: fwhost Standard Network
@@ -462,6 +473,9 @@ WARNING: translation string unused: intrusion detection system2
 WARNING: translation string unused: invalid cache size
 WARNING: translation string unused: invalid date entered
 WARNING: translation string unused: invalid downlink speed
+WARNING: translation string unused: invalid input for keepalive 1
+WARNING: translation string unused: invalid input for keepalive 1:2
+WARNING: translation string unused: invalid input for keepalive 2
 WARNING: translation string unused: invalid loaded file
 WARNING: translation string unused: invalid md5sum
 WARNING: translation string unused: invalid port list
@@ -479,6 +493,7 @@ WARNING: translation string unused: ipblocklist category invalid
 WARNING: translation string unused: ipblocklist category reputation
 WARNING: translation string unused: ipblocklist category scanner
 WARNING: translation string unused: ipfire side
+WARNING: translation string unused: ipfire side is invalid
 WARNING: translation string unused: ipsec no connections
 WARNING: translation string unused: iptable rules
 WARNING: translation string unused: javascript menu error1
@@ -497,6 +512,7 @@ WARNING: translation string unused: load printer
 WARNING: translation string unused: loaded modules
 WARNING: translation string unused: local hard disk
 WARNING: translation string unused: local master
+WARNING: translation string unused: local vpn hostname/ip
 WARNING: translation string unused: localkey
 WARNING: translation string unused: localkeyfile
 WARNING: translation string unused: locationblock country code
@@ -507,6 +523,7 @@ WARNING: translation string unused: log level
 WARNING: translation string unused: log var messages
 WARNING: translation string unused: log view
 WARNING: translation string unused: log viewer
+WARNING: translation string unused: log-options
 WARNING: translation string unused: logging
 WARNING: translation string unused: loosedirectorychecking
 WARNING: translation string unused: ls_dhcpd
@@ -543,6 +560,7 @@ WARNING: translation string unused: meaning
 WARNING: translation string unused: memory usage per
 WARNING: translation string unused: messages logging
 WARNING: translation string unused: min size
+WARNING: translation string unused: misc-options
 WARNING: translation string unused: missing dat
 WARNING: translation string unused: missing gz
 WARNING: translation string unused: modem on com1
@@ -628,10 +646,15 @@ WARNING: translation string unused: outgoing firewall reset
 WARNING: translation string unused: outgoing firewall view group
 WARNING: translation string unused: outgoing firewall warning
 WARNING: translation string unused: override mtu
+WARNING: translation string unused: ovpn add conf
 WARNING: translation string unused: ovpn config
+WARNING: translation string unused: ovpn crypt options
 WARNING: translation string unused: ovpn device
 WARNING: translation string unused: ovpn dl
 WARNING: translation string unused: ovpn engines
+WARNING: translation string unused: ovpn errmsg green already pushed
+WARNING: translation string unused: ovpn errmsg invalid ip or mask
+WARNING: translation string unused: ovpn error md5
 WARNING: translation string unused: ovpn generating the root and host certificates
 WARNING: translation string unused: ovpn log
 WARNING: translation string unused: ovpn mtu-disc
@@ -641,7 +664,13 @@ WARNING: translation string unused: ovpn mtu-disc no
 WARNING: translation string unused: ovpn mtu-disc off
 WARNING: translation string unused: ovpn mtu-disc with mssfix or fragment
 WARNING: translation string unused: ovpn mtu-disc yes
+WARNING: translation string unused: ovpn on blue
+WARNING: translation string unused: ovpn on orange
+WARNING: translation string unused: ovpn on red
 WARNING: translation string unused: ovpn reneg sec
+WARNING: translation string unused: ovpn routes push options
+WARNING: translation string unused: ovpn server status
+WARNING: translation string unused: ovpn warning rfc3280
 WARNING: translation string unused: ovpn_fastio
 WARNING: translation string unused: ovpn_mssfix
 WARNING: translation string unused: ovpn_mtudisc
@@ -723,6 +752,7 @@ WARNING: translation string unused: reset shares
 WARNING: translation string unused: resetglobals
 WARNING: translation string unused: resetpolicy
 WARNING: translation string unused: resetshares
+WARNING: translation string unused: restart ovpn server
 WARNING: translation string unused: restore hardware settings
 WARNING: translation string unused: restore settings
 WARNING: translation string unused: root
@@ -746,6 +776,7 @@ WARNING: translation string unused: selecttraffic
 WARNING: translation string unused: send email notification
 WARNING: translation string unused: send test mail
 WARNING: translation string unused: server reserved
+WARNING: translation string unused: server restart
 WARNING: translation string unused: server string
 WARNING: translation string unused: service added
 WARNING: translation string unused: service removed
@@ -756,6 +787,7 @@ WARNING: translation string unused: set
 WARNING: translation string unused: shaping add options
 WARNING: translation string unused: shaping list options
 WARNING: translation string unused: show areas
+WARNING: translation string unused: show dh
 WARNING: translation string unused: show last x lines
 WARNING: translation string unused: show lines
 WARNING: translation string unused: show share options
@@ -797,6 +829,8 @@ WARNING: translation string unused: ssport forwarding
 WARNING: translation string unused: ssproxy graphs
 WARNING: translation string unused: sssystem status
 WARNING: translation string unused: sstraffic graphs
+WARNING: translation string unused: start ovpn server
+WARNING: translation string unused: stop ovpn server
 WARNING: translation string unused: subject test
 WARNING: translation string unused: subject warn
 WARNING: translation string unused: subnet
@@ -833,6 +867,7 @@ WARNING: translation string unused: tor accounting period daily
 WARNING: translation string unused: tor accounting period monthly
 WARNING: translation string unused: tor accounting period weekly
 WARNING: translation string unused: tor bridge enabled
+WARNING: translation string unused: tor daemon
 WARNING: translation string unused: tor errmsg invalid node id
 WARNING: translation string unused: tor exit country
 WARNING: translation string unused: tor guard country
@@ -983,6 +1018,11 @@ WARNING: translation string unused: zoneconf val vlan amount assignment error
 WARNING: translation string unused: zoneconf val vlan tag assignment error
 WARNING: translation string unused: zoneconf val vlan tag range error
 WARNING: translation string unused: zoneconf val zoneslave amount error
+WARNING: untranslated string: AES-128-CBC = AES - CBC Mode - 128 Bit
+WARNING: untranslated string: AES-128-GCM = AES - GCM Mode - 128 Bit
+WARNING: untranslated string: AES-256-CBC = AES - CBC Mode - 256 Bit
+WARNING: untranslated string: AES-256-GCM = AES - GCM Mode - 256 Bit
+WARNING: untranslated string: CHACHA20-POLY1305 = ChaCha20-Poly1305
 WARNING: untranslated string: Captive ACTIVATE = unknown string
 WARNING: untranslated string: Captive clients = unknown string
 WARNING: untranslated string: Captive wrong type = Uploaded file has wrong filetype
@@ -1029,6 +1069,22 @@ WARNING: untranslated string: info messages = unknown string
 WARNING: untranslated string: max bandwidth = Maximum bandwidth
 WARNING: untranslated string: no data = unknown string
 WARNING: untranslated string: online = Online
+WARNING: untranslated string: ovpn ciphers = Ciphers
+WARNING: untranslated string: ovpn crypto settings = Cryptographic Settings
+WARNING: untranslated string: ovpn dhcp settings = DHCP Settings
+WARNING: untranslated string: ovpn dynamic client subnet = Dynamic Client Subnet
+WARNING: untranslated string: ovpn errmsg invalid route = Invalid route
+WARNING: untranslated string: ovpn fallback cipher = Fallback Cipher
+WARNING: untranslated string: ovpn fallback cipher help = This cipher is being used by clients that do not support cipher negotiation.
+WARNING: untranslated string: ovpn fqdn = FQDN
+WARNING: untranslated string: ovpn misc settings = Miscellaneous Settings
+WARNING: untranslated string: ovpn no cipher selected = No cipher selected
+WARNING: untranslated string: ovpn protocol settings = Protocol Settings
+WARNING: untranslated string: ovpn push default route = Push Default Route
+WARNING: untranslated string: ovpn roadwarrior settings = Roadwarrior Settings
+WARNING: untranslated string: ovpn routing settings = Routing Settings
+WARNING: untranslated string: ovpn transport protocol = Transport Protocol
+WARNING: untranslated string: ovpn unsupported cipher selected = Unknown cipher selected
 WARNING: untranslated string: pakfire confirm upgrades = Do you want to install all upgrades?
 WARNING: untranslated string: pakfire deps = Package dependencies:
 WARNING: untranslated string: pakfire errors = Errors occurred:
@@ -1045,6 +1101,8 @@ WARNING: untranslated string: route config changed = unknown string
 WARNING: untranslated string: routing config added = unknown string
 WARNING: untranslated string: routing config changed = unknown string
 WARNING: untranslated string: routing table = unknown string
+WARNING: untranslated string: rss = RSS
+WARNING: untranslated string: rss long = Resident Set Size
 WARNING: untranslated string: wio = unknown string
 WARNING: untranslated string: wio checked = unknown string
 WARNING: untranslated string: wio cron = unknown string
diff --git a/doc/language_issues.zh b/doc/language_issues.zh
index 92ef9269a8..d6f8cbf689 100644
--- a/doc/language_issues.zh
+++ b/doc/language_issues.zh
@@ -25,11 +25,11 @@ WARNING: translation string unused: Captive wrong ext
 WARNING: translation string unused: ConnSched scheduler
 WARNING: translation string unused: ConnSched select profile
 WARNING: translation string unused: Daily
-WARNING: translation string unused: Disabled
 WARNING: translation string unused: Existing Files
 WARNING: translation string unused: HDD temperature
 WARNING: translation string unused: Level7 rule
 WARNING: translation string unused: Local VPN IP
+WARNING: translation string unused: OVPN
 WARNING: translation string unused: Pages
 WARNING: translation string unused: Ping
 WARNING: translation string unused: Queuelenght
@@ -133,6 +133,7 @@ WARNING: translation string unused: apply
 WARNING: translation string unused: archive not exist
 WARNING: translation string unused: artist
 WARNING: translation string unused: attemps
+WARNING: translation string unused: attention
 WARNING: translation string unused: available updates
 WARNING: translation string unused: avoid dod
 WARNING: translation string unused: backup archive
@@ -178,7 +179,11 @@ WARNING: translation string unused: cannot enable both nat traversal and compres
 WARNING: translation string unused: cant enable xtaccess
 WARNING: translation string unused: capsinactive
 WARNING: translation string unused: ccd err iroute
+WARNING: translation string unused: ccd err name
 WARNING: translation string unused: ccd err netadr
+WARNING: translation string unused: ccd hint
+WARNING: translation string unused: ccd iroutehint
+WARNING: translation string unused: ccd noaddnet
 WARNING: translation string unused: cfg restart
 WARNING: translation string unused: change share
 WARNING: translation string unused: check for net traffic update
@@ -206,6 +211,8 @@ WARNING: translation string unused: cpu frequency per
 WARNING: translation string unused: cpu usage per
 WARNING: translation string unused: create mask
 WARNING: translation string unused: create new backup
+WARNING: translation string unused: crypto error
+WARNING: translation string unused: crypto warning
 WARNING: translation string unused: cryptographic settings
 WARNING: translation string unused: current media
 WARNING: translation string unused: current ovpn
@@ -239,6 +246,7 @@ WARNING: translation string unused: destination ip bad
 WARNING: translation string unused: destination ip or net
 WARNING: translation string unused: destination net
 WARNING: translation string unused: destination port overlaps
+WARNING: translation string unused: dh
 WARNING: translation string unused: dhcp base ip fixed lease
 WARNING: translation string unused: dhcp create fixed leases
 WARNING: translation string unused: dhcp fixed lease err1
@@ -246,6 +254,7 @@ WARNING: translation string unused: dhcp fixed lease help1
 WARNING: translation string unused: dhcp mode
 WARNING: translation string unused: dhcp server disabled on blue interface
 WARNING: translation string unused: dhcp server enabled on blue interface
+WARNING: translation string unused: dhcp-options
 WARNING: translation string unused: dial user password
 WARNING: translation string unused: dial user password has been changed
 WARNING: translation string unused: dialup settings
@@ -257,6 +266,7 @@ WARNING: translation string unused: disk access
 WARNING: translation string unused: display charset
 WARNING: translation string unused: display traffic at home
 WARNING: translation string unused: display webinterface effects
+WARNING: translation string unused: dl client arch insecure
 WARNING: translation string unused: dmz pinhole configuration
 WARNING: translation string unused: dmz pinhole rule added
 WARNING: translation string unused: dmz pinhole rule removed
@@ -384,6 +394,7 @@ WARNING: translation string unused: fwhost Custom Host
 WARNING: translation string unused: fwhost Custom Network
 WARNING: translation string unused: fwhost IpSec Host
 WARNING: translation string unused: fwhost IpSec Network
+WARNING: translation string unused: fwhost OpenVPN N-2-N
 WARNING: translation string unused: fwhost OpenVPN static host
 WARNING: translation string unused: fwhost OpenVPN static network
 WARNING: translation string unused: fwhost Standard Network
@@ -462,6 +473,9 @@ WARNING: translation string unused: intrusion detection system2
 WARNING: translation string unused: invalid cache size
 WARNING: translation string unused: invalid date entered
 WARNING: translation string unused: invalid downlink speed
+WARNING: translation string unused: invalid input for keepalive 1
+WARNING: translation string unused: invalid input for keepalive 1:2
+WARNING: translation string unused: invalid input for keepalive 2
 WARNING: translation string unused: invalid loaded file
 WARNING: translation string unused: invalid md5sum
 WARNING: translation string unused: invalid port list
@@ -479,6 +493,7 @@ WARNING: translation string unused: ipblocklist category invalid
 WARNING: translation string unused: ipblocklist category reputation
 WARNING: translation string unused: ipblocklist category scanner
 WARNING: translation string unused: ipfire side
+WARNING: translation string unused: ipfire side is invalid
 WARNING: translation string unused: ipsec no connections
 WARNING: translation string unused: iptable rules
 WARNING: translation string unused: javascript menu error1
@@ -497,6 +512,7 @@ WARNING: translation string unused: load printer
 WARNING: translation string unused: loaded modules
 WARNING: translation string unused: local hard disk
 WARNING: translation string unused: local master
+WARNING: translation string unused: local vpn hostname/ip
 WARNING: translation string unused: localkey
 WARNING: translation string unused: localkeyfile
 WARNING: translation string unused: locationblock country code
@@ -507,6 +523,7 @@ WARNING: translation string unused: log level
 WARNING: translation string unused: log var messages
 WARNING: translation string unused: log view
 WARNING: translation string unused: log viewer
+WARNING: translation string unused: log-options
 WARNING: translation string unused: logging
 WARNING: translation string unused: loosedirectorychecking
 WARNING: translation string unused: ls_dhcpd
@@ -543,6 +560,7 @@ WARNING: translation string unused: meaning
 WARNING: translation string unused: memory usage per
 WARNING: translation string unused: messages logging
 WARNING: translation string unused: min size
+WARNING: translation string unused: misc-options
 WARNING: translation string unused: missing dat
 WARNING: translation string unused: missing gz
 WARNING: translation string unused: modem on com1
@@ -628,10 +646,15 @@ WARNING: translation string unused: outgoing firewall reset
 WARNING: translation string unused: outgoing firewall view group
 WARNING: translation string unused: outgoing firewall warning
 WARNING: translation string unused: override mtu
+WARNING: translation string unused: ovpn add conf
 WARNING: translation string unused: ovpn config
+WARNING: translation string unused: ovpn crypt options
 WARNING: translation string unused: ovpn device
 WARNING: translation string unused: ovpn dl
 WARNING: translation string unused: ovpn engines
+WARNING: translation string unused: ovpn errmsg green already pushed
+WARNING: translation string unused: ovpn errmsg invalid ip or mask
+WARNING: translation string unused: ovpn error md5
 WARNING: translation string unused: ovpn generating the root and host certificates
 WARNING: translation string unused: ovpn log
 WARNING: translation string unused: ovpn mtu-disc
@@ -641,7 +664,13 @@ WARNING: translation string unused: ovpn mtu-disc no
 WARNING: translation string unused: ovpn mtu-disc off
 WARNING: translation string unused: ovpn mtu-disc with mssfix or fragment
 WARNING: translation string unused: ovpn mtu-disc yes
+WARNING: translation string unused: ovpn on blue
+WARNING: translation string unused: ovpn on orange
+WARNING: translation string unused: ovpn on red
 WARNING: translation string unused: ovpn reneg sec
+WARNING: translation string unused: ovpn routes push options
+WARNING: translation string unused: ovpn server status
+WARNING: translation string unused: ovpn warning rfc3280
 WARNING: translation string unused: ovpn_fastio
 WARNING: translation string unused: ovpn_mssfix
 WARNING: translation string unused: ovpn_mtudisc
@@ -723,6 +752,7 @@ WARNING: translation string unused: reset shares
 WARNING: translation string unused: resetglobals
 WARNING: translation string unused: resetpolicy
 WARNING: translation string unused: resetshares
+WARNING: translation string unused: restart ovpn server
 WARNING: translation string unused: restore hardware settings
 WARNING: translation string unused: restore settings
 WARNING: translation string unused: root
@@ -746,6 +776,7 @@ WARNING: translation string unused: selecttraffic
 WARNING: translation string unused: send email notification
 WARNING: translation string unused: send test mail
 WARNING: translation string unused: server reserved
+WARNING: translation string unused: server restart
 WARNING: translation string unused: server string
 WARNING: translation string unused: service added
 WARNING: translation string unused: service removed
@@ -756,6 +787,7 @@ WARNING: translation string unused: set
 WARNING: translation string unused: shaping add options
 WARNING: translation string unused: shaping list options
 WARNING: translation string unused: show areas
+WARNING: translation string unused: show dh
 WARNING: translation string unused: show last x lines
 WARNING: translation string unused: show lines
 WARNING: translation string unused: show share options
@@ -797,6 +829,8 @@ WARNING: translation string unused: ssport forwarding
 WARNING: translation string unused: ssproxy graphs
 WARNING: translation string unused: sssystem status
 WARNING: translation string unused: sstraffic graphs
+WARNING: translation string unused: start ovpn server
+WARNING: translation string unused: stop ovpn server
 WARNING: translation string unused: subject test
 WARNING: translation string unused: subject warn
 WARNING: translation string unused: subnet
@@ -833,6 +867,7 @@ WARNING: translation string unused: tor accounting period daily
 WARNING: translation string unused: tor accounting period monthly
 WARNING: translation string unused: tor accounting period weekly
 WARNING: translation string unused: tor bridge enabled
+WARNING: translation string unused: tor daemon
 WARNING: translation string unused: tor errmsg invalid node id
 WARNING: translation string unused: tor exit country
 WARNING: translation string unused: tor guard country
@@ -983,6 +1018,11 @@ WARNING: translation string unused: zoneconf val vlan amount assignment error
 WARNING: translation string unused: zoneconf val vlan tag assignment error
 WARNING: translation string unused: zoneconf val vlan tag range error
 WARNING: translation string unused: zoneconf val zoneslave amount error
+WARNING: untranslated string: AES-128-CBC = AES - CBC Mode - 128 Bit
+WARNING: untranslated string: AES-128-GCM = AES - GCM Mode - 128 Bit
+WARNING: untranslated string: AES-256-CBC = AES - CBC Mode - 256 Bit
+WARNING: untranslated string: AES-256-GCM = AES - GCM Mode - 256 Bit
+WARNING: untranslated string: CHACHA20-POLY1305 = ChaCha20-Poly1305
 WARNING: untranslated string: Captive ACTIVATE = unknown string
 WARNING: untranslated string: Captive clients = unknown string
 WARNING: untranslated string: Captive wrong type = Uploaded file has wrong filetype
@@ -1029,6 +1069,22 @@ WARNING: untranslated string: info messages = unknown string
 WARNING: untranslated string: max bandwidth = Maximum bandwidth
 WARNING: untranslated string: no data = unknown string
 WARNING: untranslated string: online = Online
+WARNING: untranslated string: ovpn ciphers = Ciphers
+WARNING: untranslated string: ovpn crypto settings = Cryptographic Settings
+WARNING: untranslated string: ovpn dhcp settings = DHCP Settings
+WARNING: untranslated string: ovpn dynamic client subnet = Dynamic Client Subnet
+WARNING: untranslated string: ovpn errmsg invalid route = Invalid route
+WARNING: untranslated string: ovpn fallback cipher = Fallback Cipher
+WARNING: untranslated string: ovpn fallback cipher help = This cipher is being used by clients that do not support cipher negotiation.
+WARNING: untranslated string: ovpn fqdn = FQDN
+WARNING: untranslated string: ovpn misc settings = Miscellaneous Settings
+WARNING: untranslated string: ovpn no cipher selected = No cipher selected
+WARNING: untranslated string: ovpn protocol settings = Protocol Settings
+WARNING: untranslated string: ovpn push default route = Push Default Route
+WARNING: untranslated string: ovpn roadwarrior settings = Roadwarrior Settings
+WARNING: untranslated string: ovpn routing settings = Routing Settings
+WARNING: untranslated string: ovpn transport protocol = Transport Protocol
+WARNING: untranslated string: ovpn unsupported cipher selected = Unknown cipher selected
 WARNING: untranslated string: pakfire confirm upgrades = Do you want to install all upgrades?
 WARNING: untranslated string: pakfire deps = Package dependencies:
 WARNING: untranslated string: pakfire errors = Errors occurred:
@@ -1045,6 +1101,8 @@ WARNING: untranslated string: route config changed = unknown string
 WARNING: untranslated string: routing config added = unknown string
 WARNING: untranslated string: routing config changed = unknown string
 WARNING: untranslated string: routing table = unknown string
+WARNING: untranslated string: rss = RSS
+WARNING: untranslated string: rss long = Resident Set Size
 WARNING: untranslated string: wio = unknown string
 WARNING: untranslated string: wio checked = unknown string
 WARNING: untranslated string: wio cron = unknown string
diff --git a/doc/language_missings b/doc/language_missings
index 31f0ffeda0..f1f4da85fe 100644
--- a/doc/language_missings
+++ b/doc/language_missings
@@ -5,6 +5,10 @@
 < access point name is invalid
 < access point name is required
 < advproxy update information
+< AES-128-CBC
+< AES-128-GCM
+< AES-256-CBC
+< AES-256-GCM
 < aliases default interface
 < allowed subnets
 < ansi t1.483
@@ -45,6 +49,7 @@
 < Captive heading voucher
 < Captive invalid coupon
 < Captive please enter a coupon code
+< CHACHA20-POLY1305
 < choose media
 < could not connect to www ipfire org
 < cryptographic settings
@@ -83,7 +88,23 @@
 < okay
 < oops something went wrong
 < optional
+< ovpn ciphers
+< ovpn crypto settings
+< ovpn dhcp settings
+< ovpn dynamic client subnet
+< ovpn errmsg invalid route
+< ovpn fallback cipher
+< ovpn fallback cipher help
+< ovpn fqdn
+< ovpn misc settings
+< ovpn no cipher selected
+< ovpn protocol settings
+< ovpn push default route
 < ovpn roadwarrior server
+< ovpn roadwarrior settings
+< ovpn routing settings
+< ovpn transport protocol
+< ovpn unsupported cipher selected
 < quality of service
 < quick control
 < random number generator daemon
@@ -94,6 +115,8 @@
 < remarks
 < required
 < routing
+< rss
+< rss long
 < samba server role member
 < samba server role standalone
 < shaping add options
@@ -127,21 +150,49 @@
 ############################################################################
 # Checking cgi-bin translations for language: es                           #
 ############################################################################
+< AES-128-CBC
+< AES-128-GCM
+< AES-256-CBC
+< AES-256-GCM
+< CHACHA20-POLY1305
 < dns servers
 < ids provider eol
 < indirect target selection
 < mdstat
 < online
+< ovpn ciphers
+< ovpn crypto settings
+< ovpn dhcp settings
+< ovpn dynamic client subnet
+< ovpn errmsg invalid route
+< ovpn fallback cipher
+< ovpn fallback cipher help
+< ovpn fqdn
+< ovpn misc settings
+< ovpn no cipher selected
+< ovpn protocol settings
+< ovpn push default route
+< ovpn roadwarrior settings
+< ovpn routing settings
+< ovpn transport protocol
+< ovpn unsupported cipher selected
 < quality of service
+< rss
+< rss long
 ############################################################################
 # Checking cgi-bin translations for language: fr                           #
 ############################################################################
+< AES-128-CBC
+< AES-128-GCM
+< AES-256-CBC
+< AES-256-GCM
 < allowed subnets
 < ansi t1.483
 < bewan adsl pci st
 < bewan adsl usb
 < bypassed
 < ca name must only contain characters or spaces
+< CHACHA20-POLY1305
 < configuration file
 < data transfer
 < done
@@ -175,7 +226,23 @@
 < mdstat
 < online
 < oops something went wrong
+< ovpn ciphers
+< ovpn crypto settings
+< ovpn dhcp settings
+< ovpn dynamic client subnet
+< ovpn errmsg invalid route
+< ovpn fallback cipher
+< ovpn fallback cipher help
+< ovpn fqdn
+< ovpn misc settings
+< ovpn no cipher selected
+< ovpn protocol settings
+< ovpn push default route
 < ovpn roadwarrior server
+< ovpn roadwarrior settings
+< ovpn routing settings
+< ovpn transport protocol
+< ovpn unsupported cipher selected
 < password has quotation mark
 < processors
 < public key
@@ -185,6 +252,8 @@
 < remarks
 < remote subnets
 < routing
+< rss
+< rss long
 < scanned
 < system time
 < timeformat
@@ -271,6 +340,10 @@
 < advproxy wpad label dst_noproxy_url
 < advproxy wpad title
 < advproxy wpad view pac
+< AES-128-CBC
+< AES-128-GCM
+< AES-256-CBC
+< AES-256-GCM
 < aliases default interface
 < allowed subnets
 < asn lookup failed
@@ -349,6 +422,7 @@
 < Captive vout
 < Captive WiFi coupon
 < Captive wrong type
+< CHACHA20-POLY1305
 < check all
 < configuration file
 < core update
@@ -374,7 +448,6 @@
 < disable
 < Disabled
 < disconnected
-< dl client arch insecure
 < dns check servers
 < dns configuration
 < dns could not add server
@@ -631,11 +704,27 @@
 < outgoing compression in bytes per second
 < outgoing overhead in bytes per second
 < ovpn add conf
+< ovpn ciphers
 < ovpn connection name
+< ovpn crypto settings
+< ovpn dhcp settings
+< ovpn dynamic client subnet
+< ovpn errmsg invalid route
 < ovpn error md5
+< ovpn fallback cipher
+< ovpn fallback cipher help
+< ovpn fqdn
+< ovpn misc settings
+< ovpn no cipher selected
+< ovpn protocol settings
+< ovpn push default route
 < ovpn roadwarrior server
+< ovpn roadwarrior settings
+< ovpn routing settings
 < ovpn rw connection log
 < ovpn tls auth
+< ovpn transport protocol
+< ovpn unsupported cipher selected
 < ovpn warning rfc3280
 < pakfire already busy
 < pakfire finished
@@ -674,6 +763,8 @@
 < required field
 < retbleed
 < routing
+< rss
+< rss long
 < runmode
 < samba join a domain
 < samba join domain
@@ -884,6 +975,10 @@
 < advproxy wpad label dst_noproxy_url
 < advproxy wpad title
 < advproxy wpad view pac
+< AES-128-CBC
+< AES-128-GCM
+< AES-256-CBC
+< AES-256-GCM
 < aliases default interface
 < allowed subnets
 < asn lookup failed
@@ -964,6 +1059,7 @@
 < Captive vout
 < Captive WiFi coupon
 < Captive wrong type
+< CHACHA20-POLY1305
 < check all
 < configuration file
 < cpu frequency
@@ -1268,16 +1364,31 @@
 < outgoing compression in bytes per second
 < outgoing overhead in bytes per second
 < ovpn add conf
+< ovpn ciphers
 < ovpn connection name
-< ovpn crypt options
+< ovpn crypto settings
+< ovpn dhcp settings
+< ovpn dynamic client subnet
 < ovpn engines
+< ovpn errmsg invalid route
 < ovpn error md5
+< ovpn fallback cipher
+< ovpn fallback cipher help
+< ovpn fqdn
 < ovpn generating the root and host certificates
 < ovpn ha
+< ovpn misc settings
+< ovpn no cipher selected
+< ovpn protocol settings
+< ovpn push default route
 < ovpn reneg sec
 < ovpn roadwarrior server
+< ovpn roadwarrior settings
+< ovpn routing settings
 < ovpn rw connection log
 < ovpn tls auth
+< ovpn transport protocol
+< ovpn unsupported cipher selected
 < ovpn warning rfc3280
 < pakfire already busy
 < pakfire finished
@@ -1312,6 +1423,8 @@
 < required field
 < retbleed
 < routing
+< rss
+< rss long
 < runmode
 < samba join a domain
 < samba join domain
@@ -1530,6 +1643,10 @@
 < advproxy wpad label dst_noproxy_url
 < advproxy wpad title
 < advproxy wpad view pac
+< AES-128-CBC
+< AES-128-GCM
+< AES-256-CBC
+< AES-256-GCM
 < age second
 < age seconds
 < age shour
@@ -1656,6 +1773,7 @@
 < ccd routes
 < ccd subnet
 < ccd used
+< CHACHA20-POLY1305
 < check all
 < community rules
 < configuration file
@@ -1695,7 +1813,6 @@
 < disable
 < Disabled
 < disconnected
-< dl client arch insecure
 < dnat address
 < dns check servers
 < dns configuration
@@ -2224,15 +2341,23 @@
 < outgoing firewall access
 < outgoing overhead in bytes per second
 < ovpn add conf
+< ovpn ciphers
 < ovpn connection name
-< ovpn crypt options
+< ovpn crypto settings
+< ovpn dhcp settings
+< ovpn dynamic client subnet
 < ovpn engines
 < ovpn errmsg green already pushed
 < ovpn errmsg invalid ip or mask
+< ovpn errmsg invalid route
 < ovpn error md5
+< ovpn fallback cipher
+< ovpn fallback cipher help
+< ovpn fqdn
 < ovpn generating the root and host certificates
 < ovpn ha
 < ovpn mgmt in root range
+< ovpn misc settings
 < ovpn mtu-disc
 < ovpn mtu-disc and mtu not 1500
 < ovpn mtu-disc maybe
@@ -2240,14 +2365,20 @@
 < ovpn mtu-disc off
 < ovpn mtu-disc with mssfix or fragment
 < ovpn mtu-disc yes
+< ovpn no cipher selected
 < ovpn no connections
 < ovpn port in root range
+< ovpn protocol settings
+< ovpn push default route
 < ovpn reneg sec
 < ovpn roadwarrior server
+< ovpn roadwarrior settings
 < ovpn routes push
-< ovpn routes push options
+< ovpn routing settings
 < ovpn rw connection log
 < ovpn tls auth
+< ovpn transport protocol
+< ovpn unsupported cipher selected
 < ovpn warning rfc3280
 < pakfire already busy
 < pakfire finished
@@ -2293,6 +2424,8 @@
 < required field
 < retbleed
 < routing
+< rss
+< rss long
 < runmode
 < samba join a domain
 < samba join domain
@@ -2617,6 +2750,10 @@
 < advproxy wpad label dst_noproxy_url
 < advproxy wpad title
 < advproxy wpad view pac
+< AES-128-CBC
+< AES-128-GCM
+< AES-256-CBC
+< AES-256-GCM
 < age second
 < age seconds
 < age shour
@@ -2743,6 +2880,7 @@
 < ccd routes
 < ccd subnet
 < ccd used
+< CHACHA20-POLY1305
 < check all
 < community rules
 < configuration file
@@ -2784,7 +2922,6 @@
 < Disabled
 < disconnected
 < disk access
-< dl client arch insecure
 < dnat address
 < dns check servers
 < dns configuration
@@ -3319,13 +3456,21 @@
 < outgoing overhead in bytes per second
 < outgoing traffic in bytes per second
 < ovpn add conf
+< ovpn ciphers
 < ovpn connection name
-< ovpn crypt options
+< ovpn crypto settings
+< ovpn dhcp settings
+< ovpn dynamic client subnet
 < ovpn engines
+< ovpn errmsg invalid route
 < ovpn error md5
+< ovpn fallback cipher
+< ovpn fallback cipher help
+< ovpn fqdn
 < ovpn generating the root and host certificates
 < ovpn ha
 < ovpn mgmt in root range
+< ovpn misc settings
 < ovpn mtu-disc
 < ovpn mtu-disc and mtu not 1500
 < ovpn mtu-disc maybe
@@ -3333,12 +3478,19 @@
 < ovpn mtu-disc off
 < ovpn mtu-disc with mssfix or fragment
 < ovpn mtu-disc yes
+< ovpn no cipher selected
 < ovpn no connections
 < ovpn port in root range
+< ovpn protocol settings
+< ovpn push default route
 < ovpn reneg sec
 < ovpn roadwarrior server
+< ovpn roadwarrior settings
+< ovpn routing settings
 < ovpn rw connection log
 < ovpn tls auth
+< ovpn transport protocol
+< ovpn unsupported cipher selected
 < ovpn warning rfc3280
 < pakfire already busy
 < pakfire finished
@@ -3384,6 +3536,8 @@
 < required field
 < retbleed
 < routing
+< rss
+< rss long
 < runmode
 < samba join a domain
 < samba join domain
@@ -3694,6 +3848,10 @@
 < advproxy wpad label dst_noproxy_url
 < advproxy wpad title
 < advproxy wpad view pac
+< AES-128-CBC
+< AES-128-GCM
+< AES-256-CBC
+< AES-256-GCM
 < aliases default interface
 < allowed subnets
 < asn lookup failed
@@ -3718,6 +3876,7 @@
 < cake profile raw 0
 < ca name must only contain characters or spaces
 < Captive delete logo
+< CHACHA20-POLY1305
 < configuration file
 < core update
 < cpu frequency
@@ -3916,11 +4075,27 @@
 < openvpn cert has expired
 < optional
 < otp qrcode
+< ovpn ciphers
 < ovpn connection name
+< ovpn crypto settings
+< ovpn dhcp settings
+< ovpn dynamic client subnet
+< ovpn errmsg invalid route
 < ovpn error md5
+< ovpn fallback cipher
+< ovpn fallback cipher help
+< ovpn fqdn
+< ovpn misc settings
+< ovpn no cipher selected
+< ovpn protocol settings
+< ovpn push default route
 < ovpn roadwarrior server
+< ovpn roadwarrior settings
+< ovpn routing settings
 < ovpn rw connection log
 < ovpn tls auth
+< ovpn transport protocol
+< ovpn unsupported cipher selected
 < ovpn warning rfc3280
 < pakfire already busy
 < pakfire finished
@@ -3954,6 +4129,8 @@
 < required
 < retbleed
 < routing
+< rss
+< rss long
 < runmode
 < samba server role member
 < samba server role standalone
@@ -4095,13 +4272,34 @@
 # Checking cgi-bin translations for language: tw                           #
 ############################################################################
 < advproxy errmsg invalid user/password
+< AES-128-CBC
+< AES-128-GCM
+< AES-256-CBC
+< AES-256-GCM
 < aliases default interface
 < Captive wrong type
+< CHACHA20-POLY1305
 < dns servers
 < guaranteed bandwidth
 < indirect target selection
 < max bandwidth
 < online
+< ovpn ciphers
+< ovpn crypto settings
+< ovpn dhcp settings
+< ovpn dynamic client subnet
+< ovpn errmsg invalid route
+< ovpn fallback cipher
+< ovpn fallback cipher help
+< ovpn fqdn
+< ovpn misc settings
+< ovpn no cipher selected
+< ovpn protocol settings
+< ovpn push default route
+< ovpn roadwarrior settings
+< ovpn routing settings
+< ovpn transport protocol
+< ovpn unsupported cipher selected
 < pakfire confirm upgrades
 < pakfire deps
 < pakfire errors
@@ -4114,17 +4312,40 @@
 < pakfire remove package
 < pakfire updating
 < password has quotation mark
+< rss
+< rss long
 ############################################################################
 # Checking cgi-bin translations for language: zh                           #
 ############################################################################
 < advproxy errmsg invalid user/password
+< AES-128-CBC
+< AES-128-GCM
+< AES-256-CBC
+< AES-256-GCM
 < aliases default interface
 < Captive wrong type
+< CHACHA20-POLY1305
 < dns servers
 < guaranteed bandwidth
 < indirect target selection
 < max bandwidth
 < online
+< ovpn ciphers
+< ovpn crypto settings
+< ovpn dhcp settings
+< ovpn dynamic client subnet
+< ovpn errmsg invalid route
+< ovpn fallback cipher
+< ovpn fallback cipher help
+< ovpn fqdn
+< ovpn misc settings
+< ovpn no cipher selected
+< ovpn protocol settings
+< ovpn push default route
+< ovpn roadwarrior settings
+< ovpn routing settings
+< ovpn transport protocol
+< ovpn unsupported cipher selected
 < pakfire confirm upgrades
 < pakfire deps
 < pakfire errors
@@ -4137,3 +4358,5 @@
 < pakfire remove package
 < pakfire updating
 < password has quotation mark
+< rss
+< rss long
diff --git a/html/cgi-bin/ovpnmain.cgi b/html/cgi-bin/ovpnmain.cgi
index 92a72d7539..0be4ea0b2d 100644
--- a/html/cgi-bin/ovpnmain.cgi
+++ b/html/cgi-bin/ovpnmain.cgi
@@ -19,39 +19,72 @@
 #                                                                             #
 ###############################################################################
 
+use strict;
+use Archive::Zip qw(:ERROR_CODES :CONSTANTS);
 use CGI;
 use CGI qw/:standard/;
+use Date::Parse;
+use File::Copy;
+use File::Temp qw/ tempfile tempdir /;
 use Imager::QRCode;
 use MIME::Base32;
 use MIME::Base64;
-use URI::Encode qw(uri_encode uri_decode);;
 use Net::DNS;
 use Net::Ping;
 use Net::Telnet;
-use File::Copy;
-use File::Temp qw/ tempfile tempdir /;
-use strict;
-use Archive::Zip qw(:ERROR_CODES :CONSTANTS);
 use Sort::Naturally;
-use Date::Parse;
+use URI::Encode qw(uri_encode uri_decode);;
+
 require '/var/ipfire/general-functions.pl';
-require "${General::swroot}/lang.pl";
 require "${General::swroot}/header.pl";
 require "${General::swroot}/countries.pl";
 require "${General::swroot}/location-functions.pl";
 
 # enable only the following on debugging purpose
-#use warnings;
-#use CGI::Carp 'fatalsToBrowser';
+use warnings;
+use CGI::Carp 'fatalsToBrowser';
 
-#workaround to suppress a warning when a variable is used only once
-my @dummy = ( ${Header::colourgreen}, ${Header::colourblue} );
-undef (@dummy);
-
-my %color = ();
 my %mainsettings = ();
 &General::readhash("${General::swroot}/main/settings", \%mainsettings);
-&General::readhash("/srv/web/ipfire/html/themes/ipfire/include/colors.txt", \%color);
+
+# Supported ciphers for NCP
+my @SUPPORTED_CIPHERS = (
+	"AES-256-GCM",
+	"AES-128-GCM",
+	"AES-256-CBC",
+	"AES-128-CBC",
+	"CHACHA20-POLY1305",
+);
+
+my @LEGACY_CIPHERS = (
+	"BF-CBC",
+	"CAST5-CBC",
+	"DES-CBC",
+	"DESX-CBC",
+	"SEED-CBC",
+);
+
+my @LEGACY_AUTHS = (
+	"whirlpool",
+);
+
+# Translations for the cipher selection
+my %CIPHERS = (
+	# AES
+	"AES-256-GCM" => $Lang::tr{'AES-256-GCM'},
+	"AES-128-GCM" => $Lang::tr{'AES-128-GCM'},
+	"AES-256-CBC" => $Lang::tr{'AES-256-CBC'},
+	"AES-128-CBC" => $Lang::tr{'AES-128-CBC'},
+
+	# ChaCha20-Poly1305
+	"CHACHA20-POLY1305" => $Lang::tr{'CHACHA20-POLY1305'},
+);
+
+# Use the precomputed DH paramter from RFC7919
+my $DHPARAM = "/etc/ssl/ffdhe4096.pem";
+
+my $RW_PID    = "/var/run/openvpn-rw.pid";
+my $RW_STATUS = "/var/run/openvpn-rw.log";
 
 ###
 ### Initialize variables
@@ -59,89 +92,58 @@ my %mainsettings = ();
 my %ccdconfhash=();
 my %ccdroutehash=();
 my %ccdroute2hash=();
-my %netsettings=();
-my %cgiparams=();
 my %vpnsettings=();
 my %checked=();
 my %confighash=();
 my %cahash=();
 my %selected=();
+my %cgiparams = ();
 my $warnmessage = '';
 my $errormessage = '';
-my $cryptoerror = '';
-my $cryptowarning = '';
 my %settings=();
-my $routes_push_file = '';
+my $routes_push_file = "${General::swroot}/ovpn/routes_push";
 my $confighost="${General::swroot}/fwhosts/customhosts";
 my $configgrp="${General::swroot}/fwhosts/customgroups";
 my $customnet="${General::swroot}/fwhosts/customnetworks";
 my $name;
 my $col="";
-my $local_serverconf = "${General::swroot}/ovpn/scripts/server.conf.local";
-my $local_clientconf = "${General::swroot}/ovpn/scripts/client.conf.local";
-my $dhparameter = "/etc/ssl/ffdhe4096.pem";
-
-&General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
-$cgiparams{'ENABLED'} = 'off';
-$cgiparams{'ENABLED_BLUE'} = 'off';
-$cgiparams{'ENABLED_ORANGE'} = 'off';
-$cgiparams{'EDIT_ADVANCED'} = 'off';
-$cgiparams{'NAT'} = 'off';
-$cgiparams{'COMPRESSION'} = 'off';
-$cgiparams{'ONLY_PROPOSED'} = 'off';
-$cgiparams{'ACTION'} = '';
-$cgiparams{'CA_NAME'} = '';
-$cgiparams{'DHCP_DOMAIN'} = '';
-$cgiparams{'DHCP_DNS'} = '';
-$cgiparams{'DHCP_WINS'} = '';
-$cgiparams{'ROUTES_PUSH'} = '';
-$cgiparams{'DCOMPLZO'} = 'off';
-$cgiparams{'MSSFIX'} = '';
-$cgiparams{'number'} = '';
-$cgiparams{'DCIPHER'} = '';
-$cgiparams{'DAUTH'} = '';
-$cgiparams{'TLSAUTH'} = '';
-$routes_push_file = "${General::swroot}/ovpn/routes_push";
-# Perform crypto and configration test
-&pkiconfigcheck;
-
-# Add CCD files if not already presant
-unless (-e $routes_push_file) {
-	open(RPF, ">$routes_push_file");
-	close(RPF);
-}
-unless (-e "${General::swroot}/ovpn/ccd.conf") {
-	open(CCDC, ">${General::swroot}/ovpn/ccd.conf");
-	close (CCDC);
-}
-unless (-e "${General::swroot}/ovpn/ccdroute") {
-	open(CCDR, ">${General::swroot}/ovpn/ccdroute");
-	close (CCDR);
-}
-unless (-e "${General::swroot}/ovpn/ccdroute2") {
-	open(CCDRT, ">${General::swroot}/ovpn/ccdroute2");
-	close (CCDRT);
-}
-# Add additional configs if not already presant
-unless (-e "$local_serverconf") {
-	open(LSC, ">$local_serverconf");
-       close (LSC);
-}
-unless (-e "$local_clientconf") {
-       open(LCC, ">$local_clientconf");
-       close (LCC);
-}
 
+# Load the configuration (once)
+&General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
+&read_routepushfile(\%vpnsettings);
+
+
+# Configure any defaults
+&General::set_defaults(\%vpnsettings, {
+	# The RW Server is disabled by default
+	"ENABLED"      => "off",
+	"VPN_IP"       => "$mainsettings{'HOSTNAME'}.$mainsettings{'DOMAINNAME'}",
+	"DOVPN_SUBNET" => sprintf("10.%d.%d.0/24", rand(256), rand(256)),
+
+	# Cryptographic Settings
+	"DATACIPHERS"  => "AES-256-GCM|AES-128-GCM|CHACHA20-POLY1305",
+	"DAUTH"        => "SHA512",
+	"DCIPHER"      => "", # no fallback cipher
+
+	# Advanced Settings
+	"DPROTOCOL"    => "udp",
+	"DDEST_PORT"   => 1194,
+	"DMTU"         => 1500,
+	"MAX_CLIENTS"  => 100,
+	"MSSFIX"       => "off",
+	"TLSAUTH"      => "on",
+});
+
+# Load CGI parameters
 &Header::getcgihash(\%cgiparams, {'wantfile' => 1, 'filevar' => 'FH'});
 
-# prepare openvpn config file
 ###
 ### Useful functions
 ###
 sub iscertlegacy
 {
 	my $file=$_[0];
-	my @certinfo = &General::system_output("/usr/bin/openssl", "pkcs12", "-info", "-nodes", 
+	my @certinfo = &General::system_output("/usr/bin/openssl", "pkcs12", "-info", "-nodes",
 	"-in", "$file.p12", "-noout", "-passin", "pass:''");
 	if (index ($certinfo[0], "MAC: sha1") != -1) {
 		return 1;
@@ -149,71 +151,54 @@ sub iscertlegacy
 	return 0;
 }
 
-sub haveOrangeNet
-{
-	if ($netsettings{'CONFIG_TYPE'} == 2) {return 1;}
-	if ($netsettings{'CONFIG_TYPE'} == 4) {return 1;}
-	return 0;
+sub is_cert_rfc3280_compliant($) {
+	my $path = shift;
+
+	my @output = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", $path);
+
+	return grep(/TLS Web Server Authentication/, @output);
 }
 
-sub haveBlueNet
-{
-	if ($netsettings{'CONFIG_TYPE'} == 3) {return 1;}
-	if ($netsettings{'CONFIG_TYPE'} == 4) {return 1;}
+sub is_legacy_cipher($) {
+	my $cipher = shift;
+
+	foreach my $c (@LEGACY_CIPHERS) {
+		return 1 if ($cipher eq $c);
+	}
+
 	return 0;
 }
 
-sub sizeformat{
-    my $bytesize = shift;
-    my $i = 0;
+sub is_legacy_auth($) {
+	my $auth = shift;
 
-    while(abs($bytesize) >= 1024){
-	$bytesize=$bytesize/1024;
-	$i++;
-	last if($i==6);
-    }
+	foreach my $a (@LEGACY_AUTHS) {
+		return 1 if ($auth eq $a);
+	}
 
-    my @units = ("Bytes","KB","MB","GB","TB","PB","EB");
-    my $newsize=(int($bytesize*100 +0.5))/100;
-    return("$newsize $units[$i]");
+	return 0;
 }
 
-sub cleanssldatabase
-{
-    if (open(FILE, ">${General::swroot}/ovpn/certs/serial")) {
-	print FILE "01";
-	close FILE;
-    }
-    if (open(FILE, ">${General::swroot}/ovpn/certs/index.txt")) {
-	print FILE "";
-	close FILE;
-    }
-    if (open(FILE, ">${General::swroot}/ovpn/certs/index.txt.attr")) {
-      print FILE "";
-      close FILE;
-    }
-    unlink ("${General::swroot}/ovpn/certs/index.txt.old");
-    unlink ("${General::swroot}/ovpn/certs/index.txt.attr.old");
-    unlink ("${General::swroot}/ovpn/certs/serial.old");
-    unlink ("${General::swroot}/ovpn/certs/01.pem");
-}
+sub cleanssldatabase() {
+	if (open(FILE, ">${General::swroot}/ovpn/certs/serial")) {
+		print FILE "01";
+		close FILE;
+	}
 
-sub newcleanssldatabase
-{
-    if (! -s "${General::swroot}/ovpn/certs/serial" )  {
-        open(FILE, ">${General::swroot}(ovpn/certs/serial");
-	print FILE "01";
-	close FILE;
-    }
-    if (! -s ">${General::swroot}/ovpn/certs/index.txt") {
-	&General::system("touch", "${General::swroot}/ovpn/certs/index.txt");
-    }
-    if (! -s ">${General::swroot}/ovpn/certs/index.txt.attr") {
-	&General::system("touch", "${General::swroot}/ovpn/certs/index.txt.attr");
-    }
-    unlink ("${General::swroot}/ovpn/certs/index.txt.old");
-    unlink ("${General::swroot}/ovpn/certs/index.txt.attr.old");
-    unlink ("${General::swroot}/ovpn/certs/serial.old");
+	if (open(FILE, ">${General::swroot}/ovpn/certs/index.txt")) {
+		print FILE "";
+		close FILE;
+	}
+
+	if (open(FILE, ">${General::swroot}/ovpn/certs/index.txt.attr")) {
+		print FILE "";
+		close FILE;
+	}
+
+	unlink("${General::swroot}/ovpn/certs/index.txt.old");
+	unlink("${General::swroot}/ovpn/certs/index.txt.attr.old");
+	unlink("${General::swroot}/ovpn/certs/serial.old");
+	unlink("${General::swroot}/ovpn/certs/01.pem");
 }
 
 sub deletebackupcert
@@ -226,52 +211,21 @@ sub deletebackupcert
 	}
 }
 
-###
-### Check for PKI and configure problems
-###
-
-sub pkiconfigcheck
-{
-	# Warning if md5 is in usage
-	if (-f "${General::swroot}/ovpn/certs/servercert.pem") {
-		my @signature = &General::system_output("/usr/bin/openssl", "x509", "-noout", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem");
-		if (grep(/md5WithRSAEncryption/, @signature) ) {
-			$cryptoerror = "$Lang::tr{'ovpn error md5'}";
-			goto CRYPTO_ERROR;
-		}
-	}
-
-	CRYPTO_ERROR:
-
-	# Warning if certificate is not compliant to RFC3280 TLS rules
-	if (-f "${General::swroot}/ovpn/certs/servercert.pem") {
-		my @extendkeyusage = &General::system_output("/usr/bin/openssl", "x509", "-noout", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem");
-		if ( ! grep(/TLS Web Server Authentication/, @extendkeyusage)) {
-			$cryptowarning = "$Lang::tr{'ovpn warning rfc3280'}";
-			goto CRYPTO_WARNING;
-		}
-	}
-
-	CRYPTO_WARNING:
-}
-
 sub writeserverconf {
-    my %sovpnsettings = ();
-    my @temp = ();
-    &General::readhash("${General::swroot}/ovpn/settings", \%sovpnsettings);
-    &read_routepushfile;
+	# Do we require the OpenSSL Legacy Provider?
+	my $requires_legacy_provider = 0;
 
     open(CONF,    ">${General::swroot}/ovpn/server.conf") or die "Unable to open ${General::swroot}/ovpn/server.conf: $!";
     flock CONF, 2;
     print CONF "#OpenVPN Server conf\n";
     print CONF "\n";
     print CONF "daemon openvpnserver\n";
-    print CONF "writepid /var/run/openvpn.pid\n";
+    print CONF "writepid $RW_PID\n";
     print CONF "#DAN prepare OpenVPN for listening on blue and orange\n";
-    print CONF ";local $sovpnsettings{'VPN_IP'}\n";
+    print CONF ";local $vpnsettings{'VPN_IP'}\n";
     print CONF "dev tun\n";
-    print CONF "proto $sovpnsettings{'DPROTOCOL'}\n";
-    print CONF "port $sovpnsettings{'DDEST_PORT'}\n";
+    print CONF "proto $vpnsettings{'DPROTOCOL'}\n";
+    print CONF "port $vpnsettings{'DDEST_PORT'}\n";
     print CONF "script-security 3\n";
     print CONF "ifconfig-pool-persist /var/ipfire/ovpn/ovpn-leases.db 3600\n";
     print CONF "client-config-dir /var/ipfire/ovpn/ccd\n";
@@ -279,22 +233,32 @@ sub writeserverconf {
     print CONF "ca ${General::swroot}/ovpn/ca/cacert.pem\n";
     print CONF "cert ${General::swroot}/ovpn/certs/servercert.pem\n";
     print CONF "key ${General::swroot}/ovpn/certs/serverkey.pem\n";
-    print CONF "dh $dhparameter\n";
-    my @tempovpnsubnet = split("\/",$sovpnsettings{'DOVPN_SUBNET'});
-    print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n";
-    #print CONF "push \"route $netsettings{'GREEN_NETADDRESS'} $netsettings{'GREEN_NETMASK'}\"\n";
+    print CONF "dh $DHPARAM\n";
 
-    print CONF "tun-mtu $sovpnsettings{'DMTU'}\n";
+	# Enable subnet topology
+	print CONF "# Topology\n";
+	print CONF "topology subnet\n\n";
 
+    my $netaddress = &Network::get_netaddress($vpnsettings{'DOVPN_SUBNET'});
+    my $subnetmask = &Network::get_netmask($vpnsettings{'DOVPN_SUBNET'});
+
+    print CONF "server $netaddress $subnetmask\n";
+    print CONF "tun-mtu $vpnsettings{'DMTU'}\n";
+
+	# Write custom routes
     if ($vpnsettings{'ROUTES_PUSH'} ne '') {
-		@temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'});
-		foreach (@temp)
-		{
-			@tempovpnsubnet = split("\/",&General::ipcidr2msk($_));
-			print CONF "push \"route " . $tempovpnsubnet[0]. " " .  $tempovpnsubnet[1] . "\"\n";
+		my @routes = split(/\|/, $vpnsettings{'ROUTES_PUSH'});
+
+		foreach my $route (@routes) {
+			my $netaddr = &Network::get_netaddress($route);
+			my $netmask = &Network::get_netmask($route);
+
+			if (defined($netaddr) && defined($netmask)) {
+				print CONF "push \"route ${netaddr} ${netmask}\"\n";
+			}
 		}
 	}
-# a.marx ccd
+
 	my %ccdconfhash=();
 	&General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
 	foreach my $key (keys %ccdconfhash) {
@@ -310,57 +274,76 @@ sub writeserverconf {
 			print CONF "route $a $b\n";
 		}
 	}
-# ccd end
 
-	if ($sovpnsettings{CLIENT2CLIENT} eq 'on') {
-	print CONF "client-to-client\n";
-    }
-    if ($sovpnsettings{MSSFIX} eq 'on') {
+    if ($vpnsettings{MSSFIX} eq 'on') {
 		print CONF "mssfix\n";
     } else {
 		print CONF "mssfix 0\n";
     }
-    if ($sovpnsettings{FRAGMENT} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') {
-		print CONF "fragment $sovpnsettings{'FRAGMENT'}\n";
+    if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{'DPROTOCOL'} ne 'tcp') {
+		print CONF "fragment $vpnsettings{'FRAGMENT'}\n";
     }
 
-    if ($sovpnsettings{KEEPALIVE_1} > 0 && $sovpnsettings{KEEPALIVE_2} > 0) {
-	print CONF "keepalive $sovpnsettings{'KEEPALIVE_1'} $sovpnsettings{'KEEPALIVE_2'}\n";
-    }
+	# Regularly send keep-alive packets
+	print CONF "keepalive 10 60\n";
+
     print CONF "status-version 1\n";
-    print CONF "status /var/run/ovpnserver.log 30\n";
-    print CONF "ncp-disable\n";
-    print CONF "cipher $sovpnsettings{DCIPHER}\n";
-	print CONF "auth $sovpnsettings{'DAUTH'}\n";
+    print CONF "status $RW_STATUS 30\n";
+
+	# Cryptography
+	if ($vpnsettings{'DATACIPHERS'} eq '') {
+		print CONF "ncp-disable\n";
+	} else {
+		print CONF "data-ciphers " . $vpnsettings{'DATACIPHERS'} =~ s/\|/:/gr . "\n";
+	}
+
+	# Enable fallback cipher?
+	if ($vpnsettings{'DCIPHER'} ne '') {
+		if (&is_legacy_cipher($vpnsettings{'DCIPHER'})) {
+			$requires_legacy_provider++;
+		}
+
+	    print CONF "data-ciphers-fallback $vpnsettings{'DCIPHER'}\n";
+	}
+
+	print CONF "auth $vpnsettings{'DAUTH'}\n";
+
+	if (&is_legacy_auth($vpnsettings{'DAUTH'})) {
+		$requires_legacy_provider++;
+	}
+
     # Set TLSv2 as minimum
     print CONF "tls-version-min 1.2\n";
 
-    if ($sovpnsettings{'TLSAUTH'} eq 'on') {
+    if ($vpnsettings{'TLSAUTH'} eq 'on') {
 	print CONF "tls-auth ${General::swroot}/ovpn/certs/ta.key\n";
     }
-    if ($sovpnsettings{DCOMPLZO} eq 'on') {
-        print CONF "comp-lzo\n";
-    }
-    if ($sovpnsettings{REDIRECT_GW_DEF1} eq 'on') {
+
+	# Compression
+	# Use migration to support clients that have compression enabled, but disable
+	# compression for everybody else.
+	print CONF "compress migrate\n";
+
+    if ($vpnsettings{REDIRECT_GW_DEF1} eq 'on') {
         print CONF "push \"redirect-gateway def1\"\n";
     }
-    if ($sovpnsettings{DHCP_DOMAIN} ne '') {
-        print CONF "push \"dhcp-option DOMAIN $sovpnsettings{DHCP_DOMAIN}\"\n";
+    if ($vpnsettings{DHCP_DOMAIN} ne '') {
+        print CONF "push \"dhcp-option DOMAIN $vpnsettings{DHCP_DOMAIN}\"\n";
     }
 
-    if ($sovpnsettings{DHCP_DNS} ne '') {
-        print CONF "push \"dhcp-option DNS $sovpnsettings{DHCP_DNS}\"\n";
+    if ($vpnsettings{DHCP_DNS} ne '') {
+        print CONF "push \"dhcp-option DNS $vpnsettings{DHCP_DNS}\"\n";
     }
 
-    if ($sovpnsettings{DHCP_WINS} ne '') {
-        print CONF "push \"dhcp-option WINS $sovpnsettings{DHCP_WINS}\"\n";
+    if ($vpnsettings{DHCP_WINS} ne '') {
+        print CONF "push \"dhcp-option WINS $vpnsettings{DHCP_WINS}\"\n";
     }
 
-    if ($sovpnsettings{MAX_CLIENTS} eq '') {
+    if ($vpnsettings{MAX_CLIENTS} eq '') {
 	print CONF "max-clients 100\n";
     }
-    if ($sovpnsettings{MAX_CLIENTS} ne '') {
-	print CONF "max-clients $sovpnsettings{MAX_CLIENTS}\n";
+    if ($vpnsettings{MAX_CLIENTS} ne '') {
+	print CONF "max-clients $vpnsettings{MAX_CLIENTS}\n";
     }
     print CONF "tls-verify /usr/lib/openvpn/verify\n";
     print CONF "crl-verify /var/ipfire/ovpn/crls/cacrl.pem\n";
@@ -370,11 +353,7 @@ sub writeserverconf {
     print CONF "group nobody\n";
     print CONF "persist-key\n";
     print CONF "persist-tun\n";
-	if ($sovpnsettings{LOG_VERB} ne '') {
-		print CONF "verb $sovpnsettings{LOG_VERB}\n";
-	} else {
-		print CONF "verb 3\n";
-	}
+	print CONF "verb 3\n";
 
     print CONF "# Log clients connecting/disconnecting\n";
     print CONF "client-connect \"/usr/sbin/openvpn-metrics client-connect\"\n";
@@ -385,239 +364,472 @@ sub writeserverconf {
     print CONF "management /var/run/openvpn.sock unix\n";
     print CONF "management-client-auth\n";
 
-    # Print server.conf.local if entries exist to server.conf
-    if ( !-z $local_serverconf  && $sovpnsettings{'ADDITIONAL_CONFIGS'} eq 'on') {
-       open (LSC, "$local_serverconf");
-               print CONF "\n#---------------------------\n";
-               print CONF "# Start of custom directives\n";
-               print CONF "# from server.conf.local\n";
-               print CONF "#---------------------------\n\n";
-       while (<LSC>) {
-               print CONF $_;
-       }
-               print CONF "\n#-----------------------------\n";
-               print CONF "# End of custom directives\n";
-               print CONF "#-----------------------------\n";
-       close (LSC);
-    }
-    print CONF "\n";
+	# Enable the legacy provider
+	if ($requires_legacy_provider > 0) {
+		print CONF "providers legacy default\n";
+	}
+
+	# Send clients a message when the server is being shut down
+	print CONF "explicit-exit-notify\n";
 
     close(CONF);
+
+	# Rewrite all CCD configurations
+	&write_ccd_configs();
 }
 
-sub emptyserverlog{
-    if (open(FILE, ">/var/run/ovpnserver.log")) {
-	flock FILE, 2;
-	print FILE "";
-	close FILE;
-    }
+##
+## CCD Name
+##
+
+# Checks a ccdname for letters, numbers and spaces
+sub validccdname($) {
+	my $name = shift;
 
+	# name should be at least one character in length
+	# but no more than 63 characters
+	if (length ($name) < 1 || length ($name) > 63) {
+		return 0;
+	}
+
+	# Only valid characters are a-z, A-Z, 0-9, space and -
+	if ($name !~ /^[a-zA-Z0-9 -]*$/) {
+		return 0;
+	}
+
+	return 1;
 }
 
-sub delccdnet
-{
-	my %ccdconfhash = ();
-	my %ccdhash = ();
-	my $ccdnetname=$_[0];
-	if (-f "${General::swroot}/ovpn/ovpnconfig"){
-		&General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
-		foreach my $key (keys %ccdhash) {
-			if ($ccdhash{$key}[32] eq $ccdnetname) {
-				$errormessage=$Lang::tr{'ccd err hostinnet'};
-				return;
-			}
+sub delccdnet($) {
+	my $name = shift;
+
+	my %conns = ();
+	my %subnets = ();
+
+	# Load all connections
+	&General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%conns);
+
+	# Check if the subnet is in use
+	foreach my $key (keys %conns) {
+		if ($conns{$key}[32] eq $name) {
+			return $Lang::tr{'ccd err hostinnet'};
 		}
 	}
-	&General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
-	foreach my $key (keys %ccdconfhash) {
-			if ($ccdconfhash{$key}[0] eq $ccdnetname){
-				delete $ccdconfhash{$key};
+
+	# Load all subnets
+	&General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%subnets);
+
+	# Remove the subnet
+	foreach my $key (keys %subnets) {
+			if ($subnets{$key}[0] eq $name){
+				delete $subnets{$key};
 			}
 	}
-	&General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
 
-	&writeserverconf;
-	return 0;
+	# Write the subnets back
+	&General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%subnets);
+
+	# Update the server configuration to remove routes
+	&writeserverconf();
 }
 
-sub addccdnet
-{
-	my %ccdconfhash=();
-	my @ccdconf=();
-	my $ccdname=$_[0];
-	my $ccdnet=$_[1];
-	my $subcidr;
-	my @ip2=();
-	my $checkup;
-	my $ccdip;
-	my $baseaddress;
-
-
-	#check name
-	if ($ccdname eq '')
-	{
-		$errormessage=$errormessage.$Lang::tr{'ccd err name'}."<br>";
-		return
-	}
-
-	if(!&General::validccdname($ccdname))
-	{
-		$errormessage=$Lang::tr{'ccd err invalidname'};
-		return;
-	}
+# Returns the network with the matching name
+sub get_cdd_network($) {
+	my $name = shift;
+	my %subnets = ();
 
-	($ccdip,$subcidr) = split (/\//,$ccdnet);
-	$subcidr=&General::iporsubtocidr($subcidr);
-	#check subnet
-	if ($subcidr > 30)
-	{
-		$errormessage=$Lang::tr{'ccd err invalidnet'};
-		return;
+	# Load all subnets
+	&General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%subnets);
+
+	# Find the matching subnet
+	foreach my $key (keys %subnets) {
+		if ($subnets{$key}[0] eq $name) {
+			return $subnets{$key}[1];
+		}
 	}
-	#check ip
-	if (!&General::validipandmask($ccdnet)){
-		$errormessage=$Lang::tr{'ccd err invalidnet'};
-		return;
+
+	return undef;
+}
+
+sub addccdnet($$) {
+	my $name = shift;
+	my $network = shift;
+
+	my %ccdconfhash = ();
+
+	# Check if the name is valid
+	unless (&validccdname($name)) {
+		return $Lang::tr{'ccd err invalidname'};
 	}
 
-	if (!$errormessage) {
-		my %ccdconfhash=();
-		$baseaddress=&General::getnetworkip($ccdip,$subcidr);
-		&General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
-		my $key = &General::findhasharraykey (\%ccdconfhash);
-		foreach my $i (0 .. 1) { $ccdconfhash{$key}[$i] = "";}
-		$ccdconfhash{$key}[0] = $ccdname;
-		$ccdconfhash{$key}[1] = $baseaddress."/".$subcidr;
-		&General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
-		&writeserverconf;
-		$cgiparams{'ccdname'}='';
-		$cgiparams{'ccdsubnet'}='';
-		return 1;
+	# Fetch the network address & prefix
+	my $address = &Network::get_netaddress($network);
+	my $prefix  = &Network::get_prefix($network);
+
+	# If we could not decode the subnet, it must be invalid
+	if (!defined $address || !defined $prefix) {
+		return $Lang::tr{'ccd err invalidnet'};
+
+	# If the network is smaller than /30, there is no point in using it
+	} elsif ($prefix > 30) {
+		return $Lang::tr{'ccd err invalidnet'};
 	}
+
+	# Read the configuration
+	&General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
+
+	# Create a new entry
+	my $key = &General::findhasharraykey(\%ccdconfhash);
+
+	# Store name
+	$ccdconfhash{$key}[0] = $name;
+	$ccdconfhash{$key}[1] = "$address/$prefix";
+
+	# Write the hash back
+	&General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
+
+	# Update the server configuration to add routes
+	&writeserverconf();
 }
 
-sub modccdnet
-{
+sub modccdnet($$) {
+	my $subnet  = shift;
+	my $newname = shift;
+	my $oldname;
 
-	my $newname=$_[0];
-	my $oldname=$_[1];
 	my %ccdconfhash=();
-	my %ccdhash=();
+	my %conns=();
 
-	# Check if the new name is valid.
-	if(!&General::validccdname($newname)) {
-		$errormessage=$Lang::tr{'ccd err invalidname'};
+	# Check if the new name is valid
+	unless (&validccdname($newname)) {
+		$errormessage = $Lang::tr{'ccd err invalidname'};
 		return;
 	}
 
+	# Load all subnets
 	&General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
+
+	# Check if the name already exists
 	foreach my $key (keys %ccdconfhash) {
-		if ($ccdconfhash{$key}[0] eq $oldname) {
-			foreach my $key1 (keys %ccdconfhash) {
-				if ($ccdconfhash{$key1}[0] eq $newname){
-					$errormessage=$errormessage.$Lang::tr{'ccd err netadrexist'};
-					return;
-				}else{
-					$ccdconfhash{$key}[0]= $newname;
-					&General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
-					last;
-				}
-			}
+		if ($ccdconfhash{$key}[0] eq $newname) {
+			return $Lang::tr{'ccd err netadrexist'};
 		}
 	}
 
-	&General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
-		foreach my $key (keys %ccdhash) {
-			if ($ccdhash{$key}[32] eq $oldname) {
-				$ccdhash{$key}[32]=$newname;
-				&General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
-				last;
-			}
+	# Update!
+	foreach my $key (keys %ccdconfhash) {
+		if ($ccdconfhash{$key}[1] eq $subnet) {
+			$oldname = $ccdconfhash{$key}[0];
+			$ccdconfhash{$key}[0] = $newname;
+			last;
 		}
+	}
 
-	return 0;
+	# Load all configurations
+	&General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%conns);
+
+	# Update all matching connections
+	foreach my $key (keys %conns) {
+		if ($conns{$key}[32] eq $oldname) {
+			$conns{$key}[32] = $newname;
+		}
+	}
+
+	# Write back the configuration
+	&General::writehasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
+	&General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%conns);
 }
-sub ccdmaxclients
-{
-	my $ccdnetwork=$_[0];
-	my @octets=();
-	my @subnet=();
-	@octets=split("\/",$ccdnetwork);
-	@subnet= split /\./, &General::cidrtosub($octets[1]);
-	my ($a,$b,$c,$d,$e);
-	$a=256-$subnet[0];
-	$b=256-$subnet[1];
-	$c=256-$subnet[2];
-	$d=256-$subnet[3];
-	$e=($a*$b*$c*$d)/4;
-	return $e-1;
+
+sub get_ccd_client_routes($) {
+	my $name = shift;
+
+	my %client_routes = ();
+	my @routes = ();
+
+	# Load all client routes
+	&General::readhasharray("${General::swroot}/ovpn/ccdroute", \%client_routes);
+
+	foreach my $key (keys %client_routes) {
+		if ($client_routes{$key}[0] eq $name) {
+			push(@routes, $client_routes{$key}[1]);
+		}
+	}
+
+	return @routes;
 }
 
-sub getccdadresses
-{
-	my $ipin=$_[0];
-	my ($ip1,$ip2,$ip3,$ip4)=split  /\./, $ipin;
-	my $cidr=$_[1];
-	chomp($cidr);
-	my $count=$_[2];
-	my $hasip=$_[3];
-	chomp($hasip);
-	my @iprange=();
-	my %ccdhash=();
-	&General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
-	$iprange[0]=$ip1.".".$ip2.".".$ip3.".".($ip4+2);
-	for (my $i=1;$i<=$count;$i++) {
-		my $tmpip=$iprange[$i-1];
-		my $stepper=$i*4;
-		$iprange[$i]= &Network::bin2ip(&Network::ip2bin($tmpip) + 4);
+sub get_ccd_server_routes($) {
+	my $name = shift;
+
+	my %server_routes = ();
+	my @routes = ();
+
+	# Load all server routes
+	&General::readhasharray("${General::swroot}/ovpn/ccdroute2", \%server_routes);
+
+	foreach my $key (keys %server_routes) {
+		if ($server_routes{$key}[0] eq $name) {
+			my $i = 1;
+
+			while (my $route = $server_routes{$key}[$i++]) {
+				push(@routes, $route);
+			}
+		}
 	}
-	my $r=0;
-	foreach my $key (keys %ccdhash) {
-		$r=0;
-		foreach  my $tmp (@iprange){
-			my ($net,$sub) = split (/\//,$ccdhash{$key}[33]);
-			if ($net eq $tmp) {
-				if ( $hasip ne  $ccdhash{$key}[33] ){
-					splice (@iprange,$r,1);
+
+	return @routes;
+}
+
+# This function rewrites all CCD configuration files upon change
+sub write_ccd_configs() {
+	my %conns = ();
+
+	# Load all configurations
+	&General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%conns);
+
+	foreach my $key (keys %conns) {
+		my $name = $conns{$key}[1];
+		my $type = $conns{$key}[3];
+
+		# Skip anything that isn't a host connection
+		next unless ($type eq "host");
+
+		my $filename = "${General::swroot}/ovpn/ccd/$conns{$key}[2]";
+
+		# Open the configuration file
+		open(CONF, ">${filename}") or die "Unable to open ${filename} for writing: $!";
+
+		# Write a header
+		print CONF "# OpenVPN Client Configuration File\n\n";
+
+		# Fetch the allocated IP address (if any)
+		my $pool    = $conns{$key}[32];
+		my $address = $conns{$key}[33];
+
+		# If the client has a dynamically allocated IP address, there is nothing to do
+		if ($pool eq "dynamic") {
+			print CONF "# This client uses the dynamic pool\n\n";
+
+		# Otherwise we need to push the selected IP address
+		} else {
+			$address = &convert_top30_ccd_allocation($address);
+
+			# Fetch the network of the pool
+			my $network = &get_cdd_network($pool);
+			my $netmask = &Network::get_netmask($network);
+
+			if (defined $address && defined $network && defined $netmask) {
+				print CONF "# Allocated IP address from $pool\n";
+				print CONF "ifconfig-push ${address} ${netmask}\n\n";
+			}
+		}
+
+		# Redirect Gateway?
+		my $redirect = $conns{$key}[34];
+
+		if ($redirect eq "on") {
+			print CONF "# Redirect all traffic to us\n";
+			print CONF "push redirect-gateway\n\n";
+		}
+
+		# DHCP Options
+		my %options = (
+			"DNS" => (
+				$conns{$key}[35],
+				$conns{$key}[36],
+			),
+
+			"WINS" => (
+				$conns{$key}[37],
+			),
+		);
+
+		print CONF "# DHCP Options";
+
+		foreach my $option (keys %options) {
+			foreach (@options{$option}) {
+				# Skip empty options
+				next if ($_ eq "");
+
+				print CONF "push \"dhcp-option $option $_\"\n";
+			}
+		}
+
+		# Newline
+		print CONF "\n";
+
+		# Networks routed to client
+		my @client_routes = &get_ccd_client_routes($name);
+
+		if (scalar @client_routes) {
+			print CONF "# Networks routed to the client\n";
+
+			foreach my $route (@client_routes) {
+				my $netaddress = &Network::get_netaddress($route);
+				my $netmask    = &Network::get_netmask($route);
+
+				if (!defined $netaddress || !defined $netmask) {
+					next;
+				}
+
+				print CONF "iroute $netaddress $netmask\n";
+			}
+
+			# Newline
+			print CONF "\n";
+		}
+
+		# Networks routed to server
+		my @server_routes = &get_ccd_server_routes($name);
+
+		if (scalar @server_routes) {
+			print CONF "# Networks routed to the server\n";
+
+			foreach my $route (@server_routes) {
+				my $netaddress = &Network::get_netaddress($route);
+				my $netmask    = &Network::get_netmask($route);
+
+				if (!defined $netaddress || !defined $netmask) {
+					next;
 				}
+
+				print CONF "push \"route $netaddress $netmask\"\n";
 			}
-			$r++;
+
+			# Newline
+			print CONF "\n";
 		}
+
+		close CONF;
 	}
-	return @iprange;
 }
 
-sub fillselectbox
-{
-	my $boxname=$_[1];
-	my ($ccdip,$subcidr) = split("/",$_[0]);
-	my $tz=$_[2];
-	my @allccdips=&getccdadresses($ccdip,$subcidr,&ccdmaxclients($ccdip."/".$subcidr),$tz);
-	print"<select name='$boxname' STYLE='font-family : arial; font-size : 9pt; width:130px;' >";
-	foreach (@allccdips) {
-		my $ip=$_."/30";
-		chomp($ip);
-		print "<option value='$ip' ";
-		if ( $ip eq $cgiparams{$boxname} ){
-			print"selected";
+sub ccdmaxclients($) {
+	my $network = shift;
+
+	# Fetch the prefix
+	my $prefix = &Network::get_prefix($network);
+
+	# Return undef on invalid input
+	if (!defined $prefix) {
+		return undef;
+	}
+
+	# We take three addresses away: the network base address, the gateway, and broadcast
+	return (1 << (32 - $prefix)) - 3;
+}
+
+# Lists all selectable CCD addresses for the given network
+sub getccdadresses($) {
+	my $network = shift;
+
+	# Collect all available addresses
+	my @addresses = ();
+
+	# Convert the network into binary
+	my ($start, $netmask) = &Network::network2bin($network);
+
+	# Fetch the broadcast address
+	my $broadcast = &Network::get_broadcast($network);
+	$broadcast = &Network::ip2bin($broadcast);
+
+	# Fail if we could not parse the network
+	if (!defined $start || !defined $netmask || !defined $broadcast) {
+		return undef;
+	}
+
+	# Skip the base address and gateway
+	$start += 2;
+
+	while ($start < $broadcast) {
+		push(@addresses, &Network::bin2ip($start++));
+	}
+
+	return @addresses;
+}
+
+sub convert_top30_ccd_allocation($) {
+	my $address = shift;
+
+	# Do nothing if the address does not end on /30
+	return $address unless ($address =~ m/\/30$/);
+
+	# Fetch the network base address
+	my $netaddress = &Network::get_netaddress($address);
+
+	# Break on invalid input
+	return undef if (!defined $netaddress);
+
+	# The client IP address was the second address of the subnet
+	return &Network::find_next_ip_address($netaddress, 2);
+}
+
+sub get_addresses_in_use($) {
+	my $network = shift;
+
+	my %conns = ();
+
+	# Load all connections
+	&General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%conns);
+
+	my @addresses = ();
+
+	# Check if the address is in use
+	foreach my $key (keys %conns) {
+		my $address = &convert_top30_ccd_allocation($conns{$key}[33]);
+
+		# Skip on invalid inputs
+		next if (!defined $address);
+
+		# If the first address is part of the network, we have a match
+		if (&Network::ip_address_in_network($address, $network)) {
+			push(@addresses, $address);
 		}
-		print ">$ip</option>";
 	}
-	print "</select>";
+
+	return @addresses;
 }
 
-sub hostsinnet
-{
-	my $name=$_[0];
-	my %ccdhash=();
-	my $i=0;
-	&General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
-	foreach my $key (keys %ccdhash) {
-		if ($ccdhash{$key}[32] eq $name){ $i++;}
+sub fillselectbox($$) {
+	my $boxname = shift;
+	my $network = shift;
+	my @selected = shift;
+
+	# Fetch all available addresses for this network
+	my @addresses = &getccdadresses($network);
+
+	# Fetch all addresses in use
+	my @addresses_in_use = &get_addresses_in_use($network);
+
+	print "<select name='$boxname'>";
+
+	foreach my $address (@addresses) {
+		print "<option value='$address'";
+
+		# Select any requested addresses
+		foreach (@selected) {
+			if ($address eq $_) {
+				print " selected";
+				goto NEXT;
+			}
+		}
+
+		# Disable any addresses that are not free
+		foreach (@addresses_in_use) {
+			if ($address eq $_) {
+				print " disabled";
+				goto NEXT;
+			}
+		}
+
+NEXT:
+		print ">$address</option>";
 	}
-	return $i;
+
+	print "</select>";
 }
 
+# XXX THIS WILL NO LONGER WORK
 sub check_routes_push
 {
 			my $val=$_[0];
@@ -686,41 +898,28 @@ sub check_ccdconf
 	return 1;
 }
 
-###
-# m.a.d net2net
-###
+# -------------------------------------------------------------------
 
-sub validdotmask
-{
-	my $ipdotmask = $_[0];
-	if (&General::validip($ipdotmask)) { return 0; }
-	if (!($ipdotmask =~ /^(.*?)\/(.*?)$/)) {  }
-	my $mask = $2;
-	if (($mask =~ /\./ )) { return 0; }
-  return 1;
-}
+sub read_routepushfile($) {
+	my $hash = shift;
 
-# -------------------------------------------------------------------
+	# Don't read the legacy file if we already have a value
+	if ($hash->{'ROUTES_PUSH'} ne "") {
+		unlink($routes_push_file);
 
-sub write_routepushfile
-{
-	open(FILE, ">$routes_push_file");
-	flock(FILE, 2);
-	if ($vpnsettings{'ROUTES_PUSH'} ne '') {
-		print FILE $vpnsettings{'ROUTES_PUSH'};
-	}
-	close(FILE);
-}
+	# This is some legacy code that reads the routes file if it is still present
+	} elsif (-e "$routes_push_file") {
+		delete $hash->{'ROUTES_PUSH'};
+
+		my @routes = ();
 
-sub read_routepushfile
-{
-	if (-e "$routes_push_file") {
 		open(FILE,"$routes_push_file");
-		delete $vpnsettings{'ROUTES_PUSH'};
-		while (<FILE>) { $vpnsettings{'ROUTES_PUSH'} .= $_ };
+		while (<FILE>) {
+			push(@routes, $_);
+		}
 		close(FILE);
-		$cgiparams{'ROUTES_PUSH'} = $vpnsettings{'ROUTES_PUSH'};
 
+		$hash->{'ROUTES_PUSH'} = join("|", @routes);
 	}
 }
 
@@ -732,7 +931,7 @@ sub writecollectdconf {
 	print COLLECTDVPN "Loadplugin openvpn\n";
 	print COLLECTDVPN "\n";
 	print COLLECTDVPN "<Plugin openvpn>\n";
-	print COLLECTDVPN "Statusfile \"/var/run/ovpnserver.log\"\n";
+	print COLLECTDVPN "Statusfile \"${RW_STATUS}\"\n";
 
 	&General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ccdhash);
 	foreach my $key (keys %ccdhash) {
@@ -748,46 +947,58 @@ sub writecollectdconf {
 	&General::system("/usr/local/bin/collectdctrl", "restart");
 }
 
-#hier die refresh page
-if ( -e "${General::swroot}/ovpn/gencanow") {
-    my $refresh = '';
-    $refresh = "<meta http-equiv='refresh' content='15;' />";
-    &Header::showhttpheaders();
-    &Header::openpage($Lang::tr{'OVPN'}, 1, $refresh);
-    &Header::openbigbox('100%', 'center');
-    &Header::openbox('100%', 'left', "$Lang::tr{'generate root/host certificates'}:");
-    print "<tr>\n<td align='center'><img src='/images/clock.gif' alt='' /></td>\n";
-    print "<td colspan='2'><font color='red'>Please be patient this realy can take some time on older hardware...</font></td></tr>\n";
-    &Header::closebox();
-    &Header::closebigbox();
-    &Header::closepage();
-    exit (0);
-}
-##hier die refresh page
-
-
-###
-### OpenVPN Server Control
-###
-if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'} ||
-    $cgiparams{'ACTION'} eq $Lang::tr{'stop ovpn server'} ||
-    $cgiparams{'ACTION'} eq $Lang::tr{'restart ovpn server'}) {
-    #start openvpn server
-    if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'}){
-    	&emptyserverlog();
-	&General::system("/usr/local/bin/openvpnctrl", "-s");
-    }
-    #stop openvpn server
-    if ($cgiparams{'ACTION'} eq $Lang::tr{'stop ovpn server'}){
-	&General::system("/usr/local/bin/openvpnctrl", "-k");
-	&emptyserverlog();
-    }
-#    #restart openvpn server
-#    if ($cgiparams{'ACTION'} eq $Lang::tr{'restart ovpn server'}){
-#workarund, till SIGHUP also works when running as nobody
-#   	system('/usr/local/bin/openvpnctrl', '-r');
-#	&emptyserverlog();
-#    }
+sub openvpn_status($) {
+	my $port = shift;
+
+	# Create a new Telnet session
+	my $telnet = new Net::Telnet(
+		Port    => $port,
+		Timeout => 1,
+		Errmode => "return",
+	);
+
+	# Connect
+	$telnet->open("127.0.0.1");
+
+	# Send a command
+	my @output = $telnet->cmd(
+		String => "state",
+		Prompt => "/(END.*\n|ERROR:.*\n)/"
+	);
+
+	my ($time, $status) = split(/\,/, $output[1]);
+
+	###
+	#CONNECTING    -- OpenVPN's initial state.
+	#WAIT          -- (Client only) Waiting for initial response from server.
+	#AUTH          -- (Client only) Authenticating with server.
+	#GET_CONFIG    -- (Client only) Downloading configuration options from server.
+	#ASSIGN_IP     -- Assigning IP address to virtual network interface.
+	#ADD_ROUTES    -- Adding routes to system.
+	#CONNECTED     -- Initialization Sequence Completed.
+	#RECONNECTING  -- A restart has occurred.
+	#EXITING       -- A graceful exit is in progress.
+	####
+
+	if ($status eq "CONNECTING") {
+		return "DISCONNECTED";
+	} elsif ($status eq "WAIT") {
+		return "DISCONNECTED";
+	} elsif ($status eq "AUTH") {
+		return "DISCONNECTED";
+	} elsif ($status eq "GET_CONFIG") {
+		return "DISCONNECTED";
+	} elsif ($status eq "ASSIGN_IP") {
+		return "DISCONNECTED";
+	} elsif ($status eq "ADD_ROUTES") {
+		return "DISCONNECTED";
+	} elsif ($status eq "RECONNECTING") {
+		return "CONNECTED";
+	} elsif ($status eq "EXITING") {
+		return "DISCONNECTED";
+	}
+
+	return $status;
 }
 
 ###
@@ -795,23 +1006,48 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'} ||
 ###
 
 if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) {
-    &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
-    #DAN do we really need (to to check) this value? Besides if we listen on blue and orange too,
-    #DAN this value has to leave.
-#new settings for daemon
-    $vpnsettings{'LOG_VERB'} = $cgiparams{'LOG_VERB'};
-    $vpnsettings{'KEEPALIVE_1'} = $cgiparams{'KEEPALIVE_1'};
-    $vpnsettings{'KEEPALIVE_2'} = $cgiparams{'KEEPALIVE_2'};
+    $vpnsettings{'DPROTOCOL'} = $cgiparams{'DPROTOCOL'};
+    $vpnsettings{'DDEST_PORT'} = $cgiparams{'DDEST_PORT'};
+    $vpnsettings{'DMTU'} = $cgiparams{'DMTU'};
     $vpnsettings{'MAX_CLIENTS'} = $cgiparams{'MAX_CLIENTS'};
     $vpnsettings{'REDIRECT_GW_DEF1'} = $cgiparams{'REDIRECT_GW_DEF1'};
-    $vpnsettings{'CLIENT2CLIENT'} = $cgiparams{'CLIENT2CLIENT'};
-    $vpnsettings{'DCOMPLZO'} = $cgiparams{'DCOMPLZO'};
-    $vpnsettings{'ADDITIONAL_CONFIGS'} = $cgiparams{'ADDITIONAL_CONFIGS'};
     $vpnsettings{'DHCP_DOMAIN'} = $cgiparams{'DHCP_DOMAIN'};
     $vpnsettings{'DHCP_DNS'} = $cgiparams{'DHCP_DNS'};
     $vpnsettings{'DHCP_WINS'} = $cgiparams{'DHCP_WINS'};
     $vpnsettings{'ROUTES_PUSH'} = $cgiparams{'ROUTES_PUSH'};
-    my @temp=();
+    $vpnsettings{'DATACIPHERS'} = $cgiparams{'DATACIPHERS'};
+    $vpnsettings{'DCIPHER'} = $cgiparams{'DCIPHER'};
+    $vpnsettings{'DAUTH'} = $cgiparams{'DAUTH'};
+    $vpnsettings{'TLSAUTH'} = $cgiparams{'TLSAUTH'};
+
+	# We must have at least one cipher selected
+	if ($cgiparams{'DATACIPHERS'} eq '') {
+		$errormessage = $Lang::tr{'ovpn no cipher selected'};
+		goto ADV_ERROR;
+	}
+
+	# Split data ciphers
+	my @dataciphers = split(/\|/, $cgiparams{'DATACIPHERS'});
+
+	# Check if all ciphers are supported
+	foreach my $cipher (@dataciphers) {
+		if (!grep(/^$cipher$/, @SUPPORTED_CIPHERS)) {
+			$errormessage = $Lang::tr{'ovpn unsupported cipher selected'};
+			goto ADV_ERROR;
+		}
+	}
+
+	# Check port
+    unless (&General::validport($cgiparams{'DDEST_PORT'})) {
+		$errormessage = $Lang::tr{'invalid port'};
+		goto ADV_ERROR;
+    }
+
+	# Check MTU
+    if (($cgiparams{'DMTU'} eq "") || (($cgiparams{'DMTU'}) < 1280 )) {
+        $errormessage = $Lang::tr{'invalid mtu input'};
+        goto ADV_ERROR;
+    }
 
     if ($cgiparams{'FRAGMENT'} eq '') {
     	delete $vpnsettings{'FRAGMENT'};
@@ -848,84 +1084,51 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) {
 		goto ADV_ERROR;
     	}
     }
+
+	# Validate pushed routes
     if ($cgiparams{'ROUTES_PUSH'} ne ''){
-	@temp = split(/\n/,$cgiparams{'ROUTES_PUSH'});
-    	undef $vpnsettings{'ROUTES_PUSH'};
+		my @temp = split(/\n/, $cgiparams{'ROUTES_PUSH'});
 
-   	foreach my $tmpip (@temp)
-	{
-		s/^\s+//g; s/\s+$//g;
+		my @routes = ();
 
-		if ($tmpip)
-		{
-			$tmpip=~s/\s*$//g;
-			unless (&General::validipandmask($tmpip)) {
-				$errormessage = "$tmpip ".$Lang::tr{'ovpn errmsg invalid ip or mask'};
-				goto ADV_ERROR;
-			}
-			my ($ip, $cidr) = split("\/",&General::ipcidr2msk($tmpip));
+		foreach my $route (@temp) {
+			chomp($route);
 
-			if ($ip eq $netsettings{'GREEN_NETADDRESS'} && $cidr eq $netsettings{'GREEN_NETMASK'}) {
-				$errormessage = $Lang::tr{'ovpn errmsg green already pushed'};
+			# Remove any excess whitespace
+			$route =~ s/^\s+//g;
+			$route =~ s/\s+$//g;
+
+			# Skip empty lines
+			next if ($route eq "");
+
+			unless (&Network::check_subnet($route)) {
+				$errormessage = "$Lang::tr{'ovpn errmsg invalid route'}: $route";
 				goto ADV_ERROR;
 			}
-# a.marx ccd
-			my %ccdroutehash=();
-			&General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
-			foreach my $key (keys %ccdroutehash) {
-				foreach my $i (1 .. $#{$ccdroutehash{$key}}) {
-					if ( $ip."/".$cidr eq $ccdroutehash{$key}[$i] ){
-						$errormessage="Route $ip\/$cidr ".$Lang::tr{'ccd err inuse'}." $ccdroutehash{$key}[0]" ;
-						goto ADV_ERROR;
-					}
-					my ($ip2,$cidr2) = split(/\//,$ccdroutehash{$key}[$i]);
-					if (&General::IpInSubnet ($ip,$ip2,$cidr2)){
-						$errormessage="Route $ip\/$cidr ".$Lang::tr{'ccd err inuse'}." $ccdroutehash{$key}[0]" ;
-						goto ADV_ERROR;
-					}
-				}
-			}
 
-# ccd end
-
-			$vpnsettings{'ROUTES_PUSH'} .= $tmpip."\n";
+			push(@routes, $route);
 		}
-	}
-    &write_routepushfile;
-	undef $vpnsettings{'ROUTES_PUSH'};
-    }
-	else {
-	undef $vpnsettings{'ROUTES_PUSH'};
-	&write_routepushfile;
+
+		$vpnsettings{'ROUTES_PUSH'} = join("|", @routes);
     }
+
     if ((length($cgiparams{'MAX_CLIENTS'}) == 0) || (($cgiparams{'MAX_CLIENTS'}) < 1 ) || (($cgiparams{'MAX_CLIENTS'}) > 1024 )) {
         $errormessage = $Lang::tr{'invalid input for max clients'};
         goto ADV_ERROR;
     }
-    if ($cgiparams{'KEEPALIVE_1'} ne '') {
-	if ($cgiparams{'KEEPALIVE_1'} !~ /^[0-9]+$/) {
-    	    $errormessage = $Lang::tr{'invalid input for keepalive 1'};
-        goto ADV_ERROR;
-	}
-    }
-    if ($cgiparams{'KEEPALIVE_2'} ne ''){
-	if ($cgiparams{'KEEPALIVE_2'} !~ /^[0-9]+$/) {
-    	    $errormessage = $Lang::tr{'invalid input for keepalive 2'};
-        goto ADV_ERROR;
+
+	# Store our configuration
+	&General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings);
+
+	# Write the server configuration
+	&writeserverconf();
+
+	# Restart the server if it is enabled
+	if ($vpnsettings{'ENABLED'} eq "on") {
+		&General::system("/usr/local/bin/openvpnctrl", "rw", "restart");
 	}
-    }
-    if ($cgiparams{'KEEPALIVE_2'} < ($cgiparams{'KEEPALIVE_1'} * 2)){
-        $errormessage = $Lang::tr{'invalid input for keepalive 1:2'};
-        goto ADV_ERROR;
-    }
-    &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings);
-    &writeserverconf();#hier ok
 }
 
-###
-# m.a.d net2net
-###
-
 if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq 'net' && $cgiparams{'SIDE'} eq 'server')
 {
 
@@ -989,7 +1192,7 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
   print SERVERCONF "ca ${General::swroot}/ovpn/ca/cacert.pem\n";
   print SERVERCONF "cert ${General::swroot}/ovpn/certs/servercert.pem\n";
   print SERVERCONF "key ${General::swroot}/ovpn/certs/serverkey.pem\n";
-  print SERVERCONF "dh $dhparameter\n";
+  print SERVERCONF "dh $DHPARAM\n";
   print SERVERCONF "# Cipher\n";
   print SERVERCONF "cipher $cgiparams{'DCIPHER'}\n";
 
@@ -1025,10 +1228,6 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
 
 }
 
-###
-# m.a.d net2net
-###
-
 if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq 'net' && $cgiparams{'SIDE'} eq 'client')
 {
 
@@ -1138,7 +1337,6 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
 ###
 
 if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cgiparams{'KEY'} eq '') {
-    &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
     #DAN do we really need (to to check) this value? Besides if we listen on blue and orange too,
     #DAN this value has to leave.
     if ($cgiparams{'ENABLED'} eq 'on'){
@@ -1154,27 +1352,27 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg
     }
     my @tmpovpnsubnet = split("\/",$cgiparams{'DOVPN_SUBNET'});
 
-    if (&General::IpInSubnet ( $netsettings{'RED_ADDRESS'},
+    if (&General::IpInSubnet ( $Network::ethernet{'RED_ADDRESS'},
 	$tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
-	$errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire RED Network $netsettings{'RED_ADDRESS'}";
+	$errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire RED Network $Network::ethernet{'RED_ADDRESS'}";
 	goto SETTINGS_ERROR;
     }
 
-    if (&General::IpInSubnet ( $netsettings{'GREEN_ADDRESS'},
+    if (&General::IpInSubnet ( $Network::ethernet{'GREEN_ADDRESS'},
 	$tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
-        $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Green Network $netsettings{'GREEN_ADDRESS'}";
+        $errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Green Network $Network::ethernet{'GREEN_ADDRESS'}";
         goto SETTINGS_ERROR;
     }
 
-    if (&General::IpInSubnet ( $netsettings{'BLUE_ADDRESS'},
+    if (&General::IpInSubnet ( $Network::ethernet{'BLUE_ADDRESS'},
 	$tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
-	$errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Blue Network $netsettings{'BLUE_ADDRESS'}";
+	$errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Blue Network $Network::ethernet{'BLUE_ADDRESS'}";
 	goto SETTINGS_ERROR;
     }
 
-    if (&General::IpInSubnet ( $netsettings{'ORANGE_ADDRESS'},
+    if (&General::IpInSubnet ( $Network::ethernet{'ORANGE_ADDRESS'},
 	$tmpovpnsubnet[0], $tmpovpnsubnet[1])) {
-	$errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Orange Network $netsettings{'ORANGE_ADDRESS'}";
+	$errormessage = "$Lang::tr{'ovpn subnet overlap'} IPFire Orange Network $Network::ethernet{'ORANGE_ADDRESS'}";
 	goto SETTINGS_ERROR;
     }
     open(ALIASES, "${General::swroot}/ethernet/aliases") or die 'Unable to open aliases file.';
@@ -1193,19 +1391,10 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg
     if ($errormessage ne ''){
 	goto SETTINGS_ERROR;
     }
-    if ($cgiparams{'ENABLED'} !~ /^(on|off)$/) {
+    if ($cgiparams{'ENABLED'} !~ /^(on|off|)$/) {
         $errormessage = $Lang::tr{'invalid input'};
         goto SETTINGS_ERROR;
     }
-    if ((length($cgiparams{'DMTU'})==0) || (($cgiparams{'DMTU'}) < 1000 )) {
-        $errormessage = $Lang::tr{'invalid mtu input'};
-        goto SETTINGS_ERROR;
-    }
-
-    unless (&General::validport($cgiparams{'DDEST_PORT'})) {
-	$errormessage = $Lang::tr{'invalid port'};
-	goto SETTINGS_ERROR;
-    }
 
 	# Create ta.key for tls-auth if not presant
 	if ($cgiparams{'TLSAUTH'} eq 'on') {
@@ -1219,42 +1408,23 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg
 		}
 	}
 
-    $vpnsettings{'ENABLED_BLUE'} = $cgiparams{'ENABLED_BLUE'};
-    $vpnsettings{'ENABLED_ORANGE'} =$cgiparams{'ENABLED_ORANGE'};
     $vpnsettings{'ENABLED'} = $cgiparams{'ENABLED'};
     $vpnsettings{'VPN_IP'} = $cgiparams{'VPN_IP'};
-#new settings for daemon
     $vpnsettings{'DOVPN_SUBNET'} = $cgiparams{'DOVPN_SUBNET'};
-    $vpnsettings{'DPROTOCOL'} = $cgiparams{'DPROTOCOL'};
-    $vpnsettings{'DDEST_PORT'} = $cgiparams{'DDEST_PORT'};
-    $vpnsettings{'DMTU'} = $cgiparams{'DMTU'};
-    $vpnsettings{'DCOMPLZO'} = $cgiparams{'DCOMPLZO'};
-    $vpnsettings{'DCIPHER'} = $cgiparams{'DCIPHER'};
-    $vpnsettings{'DAUTH'} = $cgiparams{'DAUTH'};
-    $vpnsettings{'TLSAUTH'} = $cgiparams{'TLSAUTH'};
-#wrtie enable
 
-  if ( $vpnsettings{'ENABLED_BLUE'} eq 'on' ) {
-	  &General::system("touch", "${General::swroot}/ovpn/enable_blue");
-  } else {
-	  unlink("${General::swroot}/ovpn/enable_blue");
-  }
+	# Store our configuration
+    &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings);
 
-  if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' ) {
-	  &General::system("touch", "${General::swroot}/ovpn/enable_orange");
-  } else {
-	  unlink("${General::swroot}/ovpn/enable_orange");
-  }
+	# Write the OpenVPN server configuration
+    &writeserverconf();
 
-  if ( $vpnsettings{'ENABLED'} eq 'on' ) {
-	  &General::system("touch", "${General::swroot}/ovpn/enable");
-  } else {
-	  unlink("${General::swroot}/ovpn/enable");
-  }
+	# Start/Stop the server
+	if ($vpnsettings{'ENABLED'} eq "on") {
+		&General::system("/usr/local/bin/openvpnctrl", "rw", "restart");
+	} else {
+		&General::system("/usr/local/bin/openvpnctrl", "rw", "stop");
+	}
 
-#new settings for daemon
-    &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings);
-    &writeserverconf();#hier ok
 SETTINGS_ERROR:
 ###
 ### Reset all step 2
@@ -1263,8 +1433,8 @@ SETTINGS_ERROR:
     my $file = '';
     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
 
-    # Kill all N2N connections
-    &General::system("/usr/local/bin/openvpnctrl", "-kn2n");
+    # Stop all N2N connections
+    &General::system("/usr/local/bin/openvpnctrl", "n2n", "stop");
 
     foreach my $key (keys %confighash) {
 	my $name = $confighash{$cgiparams{'$key'}}[1];
@@ -1273,7 +1443,7 @@ SETTINGS_ERROR:
 	    delete $confighash{$cgiparams{'$key'}};
 	}
 
-	&General::system("/usr/local/bin/openvpnctrl", "-drrd", "$name");
+	&General::system("/usr/local/bin/openvpnctrl", "n2n", "delete", "$name");
     }
     while ($file = glob("${General::swroot}/ovpn/ca/*")) {
 	unlink $file;
@@ -1615,7 +1785,6 @@ END
 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'generate root/host certificates'} ||
 	 $cgiparams{'ACTION'} eq $Lang::tr{'upload p12 file'}) {
 
-    &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
     if (-f "${General::swroot}/ovpn/ca/cacert.pem") {
 	$errormessage = $Lang::tr{'valid root certificate already exists'};
 	$cgiparams{'ACTION'} = '';
@@ -1810,9 +1979,6 @@ END
 	(my $city = $cgiparams{'ROOTCERT_CITY'}) =~ s/^\s*$/\./;
 	(my $state = $cgiparams{'ROOTCERT_STATE'}) =~ s/^\s*$/\./;
 
-	# refresh
-	#system ('/bin/touch', "${General::swroot}/ovpn/gencanow");
-
 	# Create the CA certificate
 	my $pid = open(OPENSSL, "|-");
 	$SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;};
@@ -1893,7 +2059,7 @@ END
 	    unlink ("${General::swroot}/ovpn/serverkey.pem");
 	    unlink ("${General::swroot}/ovpn/certs/serverreq.pem");
 	    unlink ("${General::swroot}/ovpn/certs/servercert.pem");
-	    &newcleanssldatabase();
+	    &cleanssldatabase();
 	    goto ROOTCERT_ERROR;
 	} else {
 	    unlink ("${General::swroot}/ovpn/certs/serverreq.pem");
@@ -2015,13 +2181,7 @@ END
 ### Enable/Disable connection
 ###
 
-###
-# m.a.d net2net
-###
-
 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'toggle enable disable'}) {
-
-    &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
     my $n2nactive = '';
     my @ps = &General::system_output("/bin/ps", "ax");
@@ -2036,7 +2196,7 @@ END
 			&General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
 
 			if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
-				&General::system("/usr/local/bin/openvpnctrl", "-sn2n", "$confighash{$cgiparams{'KEY'}}[1]");
+				&General::system("/usr/local/bin/openvpnctrl", "n2n", "start", "$confighash{$cgiparams{'KEY'}}[1]");
 				&writecollectdconf();
 			}
 		} else {
@@ -2046,7 +2206,7 @@ END
 
 			if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
 				if ($n2nactive ne '') {
-					&General::system("/usr/local/bin/openvpnctrl", "-kn2n", "$confighash{$cgiparams{'KEY'}}[1]");
+					&General::system("/usr/local/bin/openvpnctrl", "n2n", "stop", "$confighash{$cgiparams{'KEY'}}[1]");
 					&writecollectdconf();
 				}
 			}
@@ -2057,370 +2217,246 @@ END
 ### Download OpenVPN client package
 ###
 
-
 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'dl client arch'}) {
-    &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
-    &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
-    my $file = '';
-    my $clientovpn = '';
-    my @fileholder;
-    my $tempdir = tempdir( CLEANUP => 1 );
-    my $zippath = "$tempdir/";
-
-###
-# m.a.d net2net
-###
-
-if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
-
-        my $zipname = "$confighash{$cgiparams{'KEY'}}[1]-Client.zip";
-        my $zippathname = "$zippath$zipname";
-        $clientovpn = "$confighash{$cgiparams{'KEY'}}[1].conf";
-        my @ovsubnettemp =  split(/\./,$confighash{$cgiparams{'KEY'}}[27]);
-        my $ovsubnet =  "$ovsubnettemp[0].$ovsubnettemp[1].$ovsubnettemp[2]";
-        my $tunmtu = '';
-        my @remsubnet = split(/\//,$confighash{$cgiparams{'KEY'}}[8]);
-        my $n2nfragment = '';
-
-    open(CLIENTCONF, ">$tempdir/$clientovpn") or die "Unable to open tempfile: $!";
-    flock CLIENTCONF, 2;
-
-    my $zip = Archive::Zip->new();
-   print CLIENTCONF "# IPFire n2n Open VPN Client Config by ummeegge und m.a.d\n";
-   print CLIENTCONF "# \n";
-   print CLIENTCONF "# User Security\n";
-   print CLIENTCONF "user nobody\n";
-   print CLIENTCONF "group nobody\n";
-   print CLIENTCONF "persist-tun\n";
-   print CLIENTCONF "persist-key\n";
-   print CLIENTCONF "script-security 2\n";
-   print CLIENTCONF "# IP/DNS for remote Server Gateway\n";
-   print CLIENTCONF "remote $vpnsettings{'VPN_IP'}\n";
-   print CLIENTCONF "float\n";
-   print CLIENTCONF "# IP adresses of the VPN Subnet\n";
-   print CLIENTCONF "ifconfig $ovsubnet.2 $ovsubnet.1\n";
-   print CLIENTCONF "# Server Gateway Network\n";
-   print CLIENTCONF "route $remsubnet[0] $remsubnet[1]\n";
-   print CLIENTCONF "# tun Device\n";
-   print CLIENTCONF "dev tun\n";
-   print CLIENTCONF "#Logfile for statistics\n";
-   print CLIENTCONF "status-version 1\n";
-   print CLIENTCONF "status /var/run/openvpn/$cgiparams{'NAME'}-n2n 10\n";
-   print CLIENTCONF "# Port and Protokoll\n";
-   print CLIENTCONF "port $confighash{$cgiparams{'KEY'}}[29]\n";
-
-   if ($confighash{$cgiparams{'KEY'}}[28] eq 'tcp') {
-   print CLIENTCONF "proto tcp4-client\n";
-   print CLIENTCONF "# Packet size\n";
-   if ($confighash{$cgiparams{'KEY'}}[31] eq '') {$tunmtu = '1400'} else {$tunmtu = $confighash{$cgiparams{'KEY'}}[31]};
-   print CLIENTCONF "tun-mtu $tunmtu\n";
-   }
-
-   if ($confighash{$cgiparams{'KEY'}}[28] eq 'udp') {
-   print CLIENTCONF "proto udp4\n";
-   print CLIENTCONF "# Paketsize\n";
-   if ($confighash{$cgiparams{'KEY'}}[31] eq '') {$tunmtu = '1500'} else {$tunmtu = $confighash{$cgiparams{'KEY'}}[31]};
-   print CLIENTCONF "tun-mtu $tunmtu\n";
-   if ($confighash{$cgiparams{'KEY'}}[24] ne '') {print CLIENTCONF "fragment $confighash{$cgiparams{'KEY'}}[24]\n";}
-   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF "mssfix\n";} else { print CLIENTCONF "mssfix 0\n"; }
-   }
-   # Check host certificate if X509 is RFC3280 compliant.
-   # If not, old --ns-cert-type directive will be used.
-   # If appropriate key usage extension exists, new --remote-cert-tls directive will be used.
-   my @hostcert = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem");
-   if (! grep(/TLS Web Server Authentication/, @hostcert)) {
-               print CLIENTCONF "ns-cert-type server\n";
-   } else {
-               print CLIENTCONF "remote-cert-tls server\n";
-   }
-   print CLIENTCONF "# Auth. Client\n";
-   print CLIENTCONF "tls-client\n";
-   print CLIENTCONF "# Cipher\n";
-   print CLIENTCONF "cipher $confighash{$cgiparams{'KEY'}}[40]\n";
-    if ($confighash{$cgiparams{'KEY'}}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12") {
-	 print CLIENTCONF "pkcs12 ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12\r\n";
-     $zip->addFile( "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12", "$confighash{$cgiparams{'KEY'}}[1].p12") or die "Can't add file $confighash{$cgiparams{'KEY'}}[1].p12\n";
-   }
-
-   # If GCM cipher is used, do not use --auth
-   if (($confighash{$cgiparams{'KEY'}}[40] eq 'AES-256-GCM') ||
-       ($confighash{$cgiparams{'KEY'}}[40] eq 'AES-192-GCM') ||
-       ($confighash{$cgiparams{'KEY'}}[40] eq 'AES-128-GCM')) {
-        print CLIENTCONF unless "# HMAC algorithm\n";
-        print CLIENTCONF unless "auth $confighash{$cgiparams{'KEY'}}[39]\n";
-   } else {
-        print CLIENTCONF "# HMAC algorithm\n";
-        print CLIENTCONF "auth $confighash{$cgiparams{'KEY'}}[39]\n";
-   }
+	&General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
+	my $file = '';
+	my $clientovpn = '';
+	my @fileholder;
+	my $tempdir = tempdir( CLEANUP => 1 );
+	my $zippath = "$tempdir/";
+
+	# N2N
+	if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
+		my $zipname = "$confighash{$cgiparams{'KEY'}}[1]-Client.zip";
+		my $zippathname = "$zippath$zipname";
+		$clientovpn = "$confighash{$cgiparams{'KEY'}}[1].conf";
+		my @ovsubnettemp =  split(/\./,$confighash{$cgiparams{'KEY'}}[27]);
+		my $ovsubnet =  "$ovsubnettemp[0].$ovsubnettemp[1].$ovsubnettemp[2]";
+		my $tunmtu = '';
+		my @remsubnet = split(/\//,$confighash{$cgiparams{'KEY'}}[8]);
+		my $n2nfragment = '';
+
+		open(CLIENTCONF, ">$tempdir/$clientovpn") or die "Unable to open tempfile: $!";
+		flock CLIENTCONF, 2;
+
+		my $zip = Archive::Zip->new();
+		print CLIENTCONF "# IPFire n2n Open VPN Client Config by ummeegge und m.a.d\n";
+		print CLIENTCONF "# \n";
+		print CLIENTCONF "# User Security\n";
+		print CLIENTCONF "user nobody\n";
+		print CLIENTCONF "group nobody\n";
+		print CLIENTCONF "persist-tun\n";
+		print CLIENTCONF "persist-key\n";
+		print CLIENTCONF "script-security 2\n";
+		print CLIENTCONF "# IP/DNS for remote Server Gateway\n";
+		print CLIENTCONF "remote $vpnsettings{'VPN_IP'}\n";
+		print CLIENTCONF "float\n";
+		print CLIENTCONF "# IP adresses of the VPN Subnet\n";
+		print CLIENTCONF "ifconfig $ovsubnet.2 $ovsubnet.1\n";
+		print CLIENTCONF "# Server Gateway Network\n";
+		print CLIENTCONF "route $remsubnet[0] $remsubnet[1]\n";
+		print CLIENTCONF "# tun Device\n";
+		print CLIENTCONF "dev tun\n";
+		print CLIENTCONF "#Logfile for statistics\n";
+		print CLIENTCONF "status-version 1\n";
+		print CLIENTCONF "status /var/run/openvpn/$cgiparams{'NAME'}-n2n 10\n";
+		print CLIENTCONF "# Port and Protokoll\n";
+		print CLIENTCONF "port $confighash{$cgiparams{'KEY'}}[29]\n";
+
+		if ($confighash{$cgiparams{'KEY'}}[28] eq 'tcp') {
+			print CLIENTCONF "proto tcp4-client\n";
+			print CLIENTCONF "# Packet size\n";
+			if ($confighash{$cgiparams{'KEY'}}[31] eq '') {
+				$tunmtu = '1400';
+			} else {
+				$tunmtu = $confighash{$cgiparams{'KEY'}}[31];
+			}
+			print CLIENTCONF "tun-mtu $tunmtu\n";
+		}
 
-   if ($confighash{$cgiparams{'KEY'}}[30] eq 'on') {
-   print CLIENTCONF "# Enable Compression\n";
-   print CLIENTCONF "comp-lzo\n";
-     }
-   print CLIENTCONF "# Debug Level\n";
-   print CLIENTCONF "verb 3\n";
-   print CLIENTCONF "# Tunnel check\n";
-   print CLIENTCONF "keepalive 10 60\n";
-   print CLIENTCONF "# Start as daemon\n";
-   print CLIENTCONF "daemon $confighash{$cgiparams{'KEY'}}[1]n2n\n";
-   print CLIENTCONF "writepid /var/run/$confighash{$cgiparams{'KEY'}}[1]n2n.pid\n";
-   print CLIENTCONF "# Activate Management Interface and Port\n";
-   if ($confighash{$cgiparams{'KEY'}}[22] eq '') {print CLIENTCONF "management localhost $confighash{$cgiparams{'KEY'}}[29]\n"}
-    else {print CLIENTCONF "management localhost $confighash{$cgiparams{'KEY'}}[22]\n"};
-   print CLIENTCONF "# remsub $confighash{$cgiparams{'KEY'}}[11]\n";
-  if (&iscertlegacy("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]")) {
-    	print CLIENTCONF "providers legacy default\n";
-  }
+		if ($confighash{$cgiparams{'KEY'}}[28] eq 'udp') {
+			print CLIENTCONF "proto udp4\n";
+			print CLIENTCONF "# Paketsize\n";
+			if ($confighash{$cgiparams{'KEY'}}[31] eq '') {
+				$tunmtu = '1500';
+			} else {
+				$tunmtu = $confighash{$cgiparams{'KEY'}}[31];
+			}
+			print CLIENTCONF "tun-mtu $tunmtu\n";
+			if ($confighash{$cgiparams{'KEY'}}[24] ne '') {
+				print CLIENTCONF "fragment $confighash{$cgiparams{'KEY'}}[24]\n";
+			}
+			if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {
+				print CLIENTCONF "mssfix\n";
+			} else {
+				print CLIENTCONF "mssfix 0\n";
+			}
+		}
 
+		# Check host certificate if X509 is RFC3280 compliant.
+		# If not, old --ns-cert-type directive will be used.
+		# If appropriate key usage extension exists, new --remote-cert-tls directive will be used.
+		my @hostcert = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem");
+		if (! grep(/TLS Web Server Authentication/, @hostcert)) {
+			print CLIENTCONF "ns-cert-type server\n";
+		} else {
+			print CLIENTCONF "remote-cert-tls server\n";
+		}
+		print CLIENTCONF "# Auth. Client\n";
+		print CLIENTCONF "tls-client\n";
+		print CLIENTCONF "# Cipher\n";
+		print CLIENTCONF "cipher $confighash{$cgiparams{'KEY'}}[40]\n";
+
+		if ($confighash{$cgiparams{'KEY'}}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12") {
+			print CLIENTCONF "pkcs12 ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12\r\n";
+			$zip->addFile( "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12", "$confighash{$cgiparams{'KEY'}}[1].p12") or die "Can't add file $confighash{$cgiparams{'KEY'}}[1].p12\n";
+		}
 
+		# If GCM cipher is used, do not use --auth
+		if (($confighash{$cgiparams{'KEY'}}[40] eq 'AES-256-GCM') ||
+			($confighash{$cgiparams{'KEY'}}[40] eq 'AES-192-GCM') ||
+			($confighash{$cgiparams{'KEY'}}[40] eq 'AES-128-GCM')) {
+			print CLIENTCONF unless "# HMAC algorithm\n";
+			print CLIENTCONF unless "auth $confighash{$cgiparams{'KEY'}}[39]\n";
+		} else {
+			print CLIENTCONF "# HMAC algorithm\n";
+			print CLIENTCONF "auth $confighash{$cgiparams{'KEY'}}[39]\n";
+		}
 
-    close(CLIENTCONF);
+		if ($confighash{$cgiparams{'KEY'}}[30] eq 'on') {
+			print CLIENTCONF "# Enable Compression\n";
+			print CLIENTCONF "comp-lzo\n";
+		}
+		print CLIENTCONF "# Debug Level\n";
+		print CLIENTCONF "verb 3\n";
+		print CLIENTCONF "# Tunnel check\n";
+		print CLIENTCONF "keepalive 10 60\n";
+		print CLIENTCONF "# Start as daemon\n";
+		print CLIENTCONF "daemon $confighash{$cgiparams{'KEY'}}[1]n2n\n";
+		print CLIENTCONF "writepid /var/run/$confighash{$cgiparams{'KEY'}}[1]n2n.pid\n";
+		print CLIENTCONF "# Activate Management Interface and Port\n";
+		if ($confighash{$cgiparams{'KEY'}}[22] eq '') {
+			print CLIENTCONF "management localhost $confighash{$cgiparams{'KEY'}}[29]\n"
+		} else {
+			print CLIENTCONF "management localhost $confighash{$cgiparams{'KEY'}}[22]\n"
+		};
+		print CLIENTCONF "# remsub $confighash{$cgiparams{'KEY'}}[11]\n";
+		if (&iscertlegacy("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]")) {
+			print CLIENTCONF "providers legacy default\n";
+		}
+	    close(CLIENTCONF);
 
-    $zip->addFile( "$tempdir/$clientovpn", $clientovpn) or die "Can't add file $clientovpn\n";
-    my $status = $zip->writeToFileNamed($zippathname);
+		$zip->addFile( "$tempdir/$clientovpn", $clientovpn) or die "Can't add file $clientovpn\n";
+		my $status = $zip->writeToFileNamed($zippathname);
 
-    open(DLFILE, "<$zippathname") or die "Unable to open $zippathname: $!";
-    @fileholder = <DLFILE>;
-    print "Content-Type:application/x-download\n";
-    print "Content-Disposition:attachment;filename=$zipname\n\n";
-    print @fileholder;
-    exit (0);
-}
-else
-{
-        my $zipname = "$confighash{$cgiparams{'KEY'}}[1]-TO-IPFire.zip";
-        my $zippathname = "$zippath$zipname";
-        $clientovpn = "$confighash{$cgiparams{'KEY'}}[1]-TO-IPFire.ovpn";
+		open(DLFILE, "<$zippathname") or die "Unable to open $zippathname: $!";
+		@fileholder = <DLFILE>;
+		print "Content-Type:application/x-download\n";
+		print "Content-Disposition:attachment;filename=$zipname\n\n";
+		print @fileholder;
 
-###
-# m.a.d net2net
-###
+	# RW
+	} else {
+		my $name = $confighash{$cgiparams{'KEY'}}[1];
 
-    open(CLIENTCONF, ">$tempdir/$clientovpn") or die "Unable to open tempfile: $!";
-    flock CLIENTCONF, 2;
-
-    my $zip = Archive::Zip->new();
-
-    print CLIENTCONF "#OpenVPN Client conf\r\n";
-    print CLIENTCONF "tls-client\r\n";
-    print CLIENTCONF "client\r\n";
-    print CLIENTCONF "nobind\r\n";
-    print CLIENTCONF "dev tun\r\n";
-    print CLIENTCONF "proto $vpnsettings{'DPROTOCOL'}\r\n";
-    print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n";
-
-    if ( $vpnsettings{'ENABLED'} eq 'on'){
-    	print CLIENTCONF "remote $vpnsettings{'VPN_IP'} $vpnsettings{'DDEST_PORT'}\r\n";
-	if ( $vpnsettings{'ENABLED_BLUE'} eq 'on' && (&haveBlueNet())){
-	    print CLIENTCONF "#comment the above line and uncomment the next line, if you want to connect on the Blue interface\r\n";
-	    print CLIENTCONF ";remote $netsettings{'BLUE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
-	}
-	if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' && (&haveOrangeNet())){
-	    print CLIENTCONF "#comment the above line and uncomment the next line, if you want to connect on the Orange interface\r\n";
-	    print CLIENTCONF ";remote $netsettings{'ORANGE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
-	}
-    } elsif ( $vpnsettings{'ENABLED_BLUE'} eq 'on' && (&haveBlueNet())){
-	print CLIENTCONF "remote $netsettings{'BLUE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
-	if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' && (&haveOrangeNet())){
-	    print CLIENTCONF "#comment the above line and uncomment the next line, if you want to connect on the Orange interface\r\n";
-	    print CLIENTCONF ";remote $netsettings{'ORANGE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
-	}
-    } elsif ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' && (&haveOrangeNet())){
-	print CLIENTCONF "remote $netsettings{'ORANGE_ADDRESS'} $vpnsettings{'DDEST_PORT'}\r\n";
-    }
+		# Send HTTP Headers
+		&Header::showhttpheaders({
+			"Content-Type" => "application/x-openvpn-profile",
+			"Content-Disposition" => "attachment; filename=${name}.ovpn",
+		});
 
-    my $file_crt = new File::Temp( UNLINK => 1 );
-    my $file_key = new File::Temp( UNLINK => 1 );
-    my $include_certs = 0;
+		print "########################################################################\n";
+		print "# IPFire OpenVPN Client Configuration for \"${name}\"\n";
+		print "########################################################################\n";
 
-    if ($confighash{$cgiparams{'KEY'}}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12") {
-	if ($cgiparams{'MODE'} eq 'insecure') {
-		$include_certs = 1;
+		# This is a client
+		print "client\n";
 
-		# Add the CA
-		print CLIENTCONF ";ca cacert.pem\r\n";
-		$zip->addFile("${General::swroot}/ovpn/ca/cacert.pem", "cacert.pem")  or die "Can't add file cacert.pem\n";
+		# This is a layer 3 VPN
+		print "dev tun\n";
 
-		# Extract the certificate
-		# This system call is safe, because all arguments are passed as an array.
-		if (&iscertlegacy("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]")) {
-			system('/usr/bin/openssl', 'pkcs12', '-legacy', '-in', "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12",
-				'-clcerts', '-nokeys', '-nodes', '-out', "$file_crt" , '-passin', 'pass:');
-			if ($?) {
-				die "openssl error: $?";
-			}
-		} else {
-			system('/usr/bin/openssl', 'pkcs12', '-in', "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12",
-				'-clcerts', '-nokeys', '-nodes', '-out', "$file_crt" , '-passin', 'pass:');
-			if ($?) {
-				die "openssl error: $?";
-			}
-		}
+		# Point the client to this server
+		print "remote $vpnsettings{'VPN_IP'} $vpnsettings{'DDEST_PORT'}\n";
+		print "proto $vpnsettings{'DPROTOCOL'}\n";
 
-		$zip->addFile("$file_crt", "$confighash{$cgiparams{'KEY'}}[1].pem") or die;
-		print CLIENTCONF ";cert $confighash{$cgiparams{'KEY'}}[1].pem\r\n";
+		# Configure the MTU of the tunnel interface
+		print "tun-mtu $vpnsettings{'DMTU'}\n";
 
-		# Extract the key
-		# This system call is safe, because all arguments are passed as an array.
-		if (&iscertlegacy("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]")) {
-			system('/usr/bin/openssl', 'pkcs12', '-legacy', '-in', "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12",
-				'-nocerts', '-nodes', '-out', "$file_key", '-passin', 'pass:');
-			if ($?) {
-				die "openssl error: $?";
-			}
-		} else {
-			system('/usr/bin/openssl', 'pkcs12', '-in', "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12",
-				'-nocerts', '-nodes', '-out', "$file_key", '-passin', 'pass:');
-			if ($?) {
-				die "openssl error: $?";
-			}
+		# Ask the client to verify the server certificate
+		if (&is_cert_rfc3280_compliant("${General::swroot}/ovpn/certs/servercert.pem")) {
+			print "remote-cert-tls server\n";
 		}
+		print "verify-x509-name $vpnsettings{'ROOTCERT_HOSTNAME'} name\n";
 
-		$zip->addFile("$file_key", "$confighash{$cgiparams{'KEY'}}[1].key") or die;
-		print CLIENTCONF ";key $confighash{$cgiparams{'KEY'}}[1].key\r\n";
-	} else {
-		print CLIENTCONF "pkcs12 $confighash{$cgiparams{'KEY'}}[1].p12\r\n";
-		$zip->addFile( "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12", "$confighash{$cgiparams{'KEY'}}[1].p12") or die "Can't add file $confighash{$cgiparams{'KEY'}}[1].p12\n";
-	}
-    } else {
-	print CLIENTCONF "ca cacert.pem\r\n";
-	print CLIENTCONF "cert $confighash{$cgiparams{'KEY'}}[1]cert.pem\r\n";
-	print CLIENTCONF "key $confighash{$cgiparams{'KEY'}}[1].key\r\n";
-	$zip->addFile( "${General::swroot}/ovpn/ca/cacert.pem", "cacert.pem")  or die "Can't add file cacert.pem\n";
-	$zip->addFile( "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem", "$confighash{$cgiparams{'KEY'}}[1]cert.pem") or die "Can't add file $confighash{$cgiparams{'KEY'}}[1]cert.pem\n";
-    }
-    print CLIENTCONF "cipher $vpnsettings{DCIPHER}\r\n";
-	print CLIENTCONF "auth $vpnsettings{'DAUTH'}\r\n";
-
-    if ($vpnsettings{'TLSAUTH'} eq 'on') {
-	if ($cgiparams{'MODE'} eq 'insecure') {
-		print CLIENTCONF ";";
-	}
-	print CLIENTCONF "tls-auth ta.key\r\n";
-	$zip->addFile( "${General::swroot}/ovpn/certs/ta.key", "ta.key")  or die "Can't add file ta.key\n";
-    }
-    if ($vpnsettings{DCOMPLZO} eq 'on') {
-        print CLIENTCONF "comp-lzo\r\n";
-    }
-    print CLIENTCONF "verb 3\r\n";
-	# Check host certificate if X509 is RFC3280 compliant.
-	# If not, old --ns-cert-type directive will be used.
-	# If appropriate key usage extension exists, new --remote-cert-tls directive will be used.
-	my @hostcert = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem");
-	if (! grep(/TLS Web Server Authentication/, @hostcert)) {
-		print CLIENTCONF "ns-cert-type server\r\n";
-	} else {
-		print CLIENTCONF "remote-cert-tls server\r\n";
-	}
-    print CLIENTCONF "verify-x509-name $vpnsettings{ROOTCERT_HOSTNAME} name\r\n";
-    if ($vpnsettings{MSSFIX} eq 'on') {
-	print CLIENTCONF "mssfix\r\n";
-    } else {
-	print CLIENTCONF "mssfix 0\r\n";
-    }
-    if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne 'tcp' ) {
-	print CLIENTCONF "fragment $vpnsettings{'FRAGMENT'}\r\n";
-    }
-
-    # Disable storing any credentials in memory
-    print CLIENTCONF "auth-nocache\r\n";
-
-    # Set a fake user name for authentication
-    print CLIENTCONF "auth-user-pass\r\n";
-    print CLIENTCONF "auth-token-user USER\r\n";
-    print CLIENTCONF "auth-token TOTP\r\n";
+		if ($vpnsettings{'MSSFIX'} eq 'on') {
+			print "mssfix\n";
+	    } else {
+			print "mssfix 0\n";
+	    }
+	    if ($vpnsettings{'FRAGMENT'} ne '' && $vpnsettings{'DPROTOCOL'} ne 'tcp' ) {
+			print "fragment $vpnsettings{'FRAGMENT'}\n";
+	    }
 
-    # If the server is asking for TOTP this needs to happen interactively
-    print CLIENTCONF "auth-retry interact\r\n";
+		# We no longer send any cryptographic configuration since 2.6.
+		# That way, we will be able to push this from the server.
+		# Therefore we always mandate NCP for new clients.
 
-    # Add provider line if certificate is legacy type
-    if (&iscertlegacy("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]")) {
-	print CLIENTCONF "providers legacy default\r\n";
-    }
+		if ($vpnsettings{'DAUTH'} ne "") {
+			print "auth $vpnsettings{'DAUTH'}\n";
+		}
 
-    if ($include_certs) {
-	print CLIENTCONF "\r\n";
+		# Disable storing any credentials in memory
+		print "auth-nocache\n";
 
-	# CA
-	open(FILE, "<${General::swroot}/ovpn/ca/cacert.pem");
-	print CLIENTCONF "<ca>\r\n";
-	while (<FILE>) {
-		chomp($_);
-		print CLIENTCONF "$_\r\n";
-	}
-	print CLIENTCONF "</ca>\r\n\r\n";
-	close(FILE);
+		# Set a fake user name for authentication
+		print "auth-token-user USER\n";
+		print "auth-token TOTP\n";
 
-	# Cert
-	open(FILE, "<$file_crt");
-	print CLIENTCONF "<cert>\r\n";
-	while (<FILE>) {
-		chomp($_);
-		print CLIENTCONF "$_\r\n";
-	}
-	print CLIENTCONF "</cert>\r\n\r\n";
-	close(FILE);
+		# If the server is asking for TOTP this needs to happen interactively
+		print "auth-retry interact\n";
 
-	# Key
-	open(FILE, "<$file_key");
-	print CLIENTCONF "<key>\r\n";
-	while (<FILE>) {
-		chomp($_);
-		print CLIENTCONF "$_\r\n";
-	}
-	print CLIENTCONF "</key>\r\n\r\n";
-	close(FILE);
+		# Add provider line if certificate is legacy type
+		if (&iscertlegacy("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]")) {
+			print "providers legacy default\n";
+		}
 
-	# TLS auth
-	if ($vpnsettings{'TLSAUTH'} eq 'on') {
-		open(FILE, "<${General::swroot}/ovpn/certs/ta.key");
-		print CLIENTCONF "<tls-auth>\r\n";
+		# CA
+		open(FILE, "<${General::swroot}/ovpn/ca/cacert.pem");
+		print "\n<ca>\n";
 		while (<FILE>) {
 			chomp($_);
-			print CLIENTCONF "$_\r\n";
+			print "$_\n";
 		}
-		print CLIENTCONF "</tls-auth>\r\n\r\n";
+		print "</ca>\n";
 		close(FILE);
-	}
-    }
-
-    # Print client.conf.local if entries exist to client.ovpn
-    if (!-z $local_clientconf && $vpnsettings{'ADDITIONAL_CONFIGS'} eq 'on') {
-       open (LCC, "$local_clientconf");
-               print CLIENTCONF "\n#---------------------------\n";
-               print CLIENTCONF "# Start of custom directives\n";
-               print CLIENTCONF "# from client.conf.local\n";
-               print CLIENTCONF "#---------------------------\n\n";
-       while (<LCC>) {
-               print CLIENTCONF $_;
-       }
-               print CLIENTCONF "\n#---------------------------\n";
-               print CLIENTCONF "# End of custom directives\n";
-               print CLIENTCONF "#---------------------------\n\n";
-       close (LCC);
-    }
-    close(CLIENTCONF);
-
-    $zip->addFile( "$tempdir/$clientovpn", $clientovpn) or die "Can't add file $clientovpn\n";
-    my $status = $zip->writeToFileNamed($zippathname);
-
-    open(DLFILE, "<$zippathname") or die "Unable to open $zippathname: $!";
-    @fileholder = <DLFILE>;
-    print "Content-Type:application/x-download\n";
-    print "Content-Disposition:attachment;filename=$zipname\n\n";
-    print @fileholder;
-    exit (0);
-   }
 
+		# PKCS12
+		open(FILE, "<${General::swroot}/ovpn/certs/${name}.p12");
+		print "\n<pkcs12>\n";
+		print &MIME::Base64::encode_base64(do { local $/; <FILE> });
+		print "</pkcs12>\n";
+		close(FILE);
 
+		# TLS auth
+		if ($vpnsettings{'TLSAUTH'} eq 'on') {
+			open(FILE, "<${General::swroot}/ovpn/certs/ta.key");
+			print "\n<tls-auth>\n";
+			while (<FILE>) {
+				chomp($_);
+				print "$_\n";
+			}
+			print "</tls-auth>\n";
+			close(FILE);
+		}
+	}
 
+	exit (0);
 ###
 ### Remove connection
 ###
 
 
 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove'}) {
-	&General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
 	&General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
 
 	if ($confighash{$cgiparams{'KEY'}}) {
@@ -2428,13 +2464,9 @@ else
 		&General::system("/usr/bin/openssl", "ca", "-revoke", "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem", "-config", "/usr/share/openvpn/ovpn.cnf");
 		&General::system("/usr/bin/openssl", "ca", "-gencrl", "-out", "${General::swroot}/ovpn/crls/cacrl.pem", "-config", "/usr/share/openvpn/ovpn.cnf");
 
-###
-# m.a.d net2net
-###
-
 		if ($confighash{$cgiparams{'KEY'}}[3] eq 'net') {
 			# Stop the N2N connection before it is removed
-			&General::system("/usr/local/bin/openvpnctrl", "-kn2n", "$confighash{$cgiparams{'KEY'}}[1]");
+			&General::system("/usr/local/bin/openvpnctrl", "n2n", "stop", "$confighash{$cgiparams{'KEY'}}[1]");
 
 			my $conffile = glob("${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]/$confighash{$cgiparams{'KEY'}}[1].conf");
 			my $certfile = glob("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
@@ -2449,7 +2481,7 @@ else
 		unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem");
 		unlink ("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
 
-# A.Marx CCD delete ccd files and routes
+		# Delete CCD files and routes
 
 		if (-f "${General::swroot}/ovpn/ccd/$confighash{$cgiparams{'KEY'}}[2]")
 		{
@@ -2473,10 +2505,9 @@ else
 		&General::writehasharray("${General::swroot}/ovpn/ccdroute2", \%ccdroute2hash);
 		&writeserverconf;
 
-# CCD end
 		# Update collectd configuration and delete all RRD files of the removed connection
 		&writecollectdconf();
-		&General::system("/usr/local/bin/openvpnctrl", "-drrd", "$confighash{$cgiparams{'KEY'}}[1]");
+		&General::system("/usr/local/bin/openvpnctrl", "n2n", "delete", "$confighash{$cgiparams{'KEY'}}[1]");
 
 		delete $confighash{$cgiparams{'KEY'}};
 		&General::system("/usr/bin/openssl", "ca", "-gencrl", "-out", "${General::swroot}/ovpn/crls/cacrl.pem", "-config", "/usr/share/openvpn/ovpn.cnf");
@@ -2563,28 +2594,6 @@ END
    &Header::closepage();
    exit(0);
 
-###
-### Display Diffie-Hellman key
-###
-} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show dh'}) {
-
-    if (! -e "$dhparameter") {
-	$errormessage = $Lang::tr{'not present'};
-	} else {
-		&Header::showhttpheaders();
-		&Header::openpage($Lang::tr{'ovpn'}, 1, '');
-		&Header::openbigbox('100%', 'LEFT', '', '');
-		&Header::openbox('100%', 'LEFT', "$Lang::tr{'dh'}:");
-		my @output = &General::system_output("/usr/bin/openssl", "dhparam", "-text", "-in", "$dhparameter");
-		my $output = &Header::cleanhtml(join("", @output) ,"y");
-		print "<pre>$output</pre>\n";
-		&Header::closebox();
-		print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
-		&Header::closebigbox();
-		&Header::closepage();
-		exit(0);
-    }
-
 ###
 ### Display tls-auth key
 ###
@@ -2639,61 +2648,58 @@ END
 ###
 
 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'advanced server'}) {
-    %cgiparams = ();
-    %cahash = ();
-    %confighash = ();
-    my $disabled;
-    &General::readhash("${General::swroot}/ovpn/settings", \%cgiparams);
-    read_routepushfile;
-
-
-#    if ($cgiparams{'CLIENT2CLIENT'} eq '') {
-#	$cgiparams{'CLIENT2CLIENT'} =  'on';
-#    }
 ADV_ERROR:
-    if ($cgiparams{'MAX_CLIENTS'} eq '') {
-		$cgiparams{'MAX_CLIENTS'} =  '100';
-    }
-    if ($cgiparams{'KEEPALIVE_1'} eq '') {
-		$cgiparams{'KEEPALIVE_1'} =  '10';
-    }
-    if ($cgiparams{'KEEPALIVE_2'} eq '') {
-		$cgiparams{'KEEPALIVE_2'} =  '60';
-    }
-    if ($cgiparams{'LOG_VERB'} eq '') {
-		$cgiparams{'LOG_VERB'} =  '3';
-    }
-    if ($cgiparams{'TLSAUTH'} eq '') {
-		$cgiparams{'TLSAUTH'} = 'off';
-    }
-    $checked{'CLIENT2CLIENT'}{'off'} = '';
-    $checked{'CLIENT2CLIENT'}{'on'} = '';
-    $checked{'CLIENT2CLIENT'}{$cgiparams{'CLIENT2CLIENT'}} = 'CHECKED';
+    $selected{'DPROTOCOL'}{'udp'} = '';
+    $selected{'DPROTOCOL'}{'tcp'} = '';
+    $selected{'DPROTOCOL'}{$vpnsettings{'DPROTOCOL'}} = 'SELECTED';
+
     $checked{'REDIRECT_GW_DEF1'}{'off'} = '';
     $checked{'REDIRECT_GW_DEF1'}{'on'} = '';
-    $checked{'REDIRECT_GW_DEF1'}{$cgiparams{'REDIRECT_GW_DEF1'}} = 'CHECKED';
-    $checked{'DCOMPLZO'}{'off'} = '';
-    $checked{'DCOMPLZO'}{'on'} = '';
-    $checked{'DCOMPLZO'}{$cgiparams{'DCOMPLZO'}} = 'CHECKED';
-    $checked{'ADDITIONAL_CONFIGS'}{'off'} = '';
-    $checked{'ADDITIONAL_CONFIGS'}{'on'} = '';
-    $checked{'ADDITIONAL_CONFIGS'}{$cgiparams{'ADDITIONAL_CONFIGS'}} = 'CHECKED';
+    $checked{'REDIRECT_GW_DEF1'}{$vpnsettings{'REDIRECT_GW_DEF1'}} = 'CHECKED';
     $checked{'MSSFIX'}{'off'} = '';
     $checked{'MSSFIX'}{'on'} = '';
-    $checked{'MSSFIX'}{$cgiparams{'MSSFIX'}} = 'CHECKED';
-    $selected{'LOG_VERB'}{'0'} = '';
-    $selected{'LOG_VERB'}{'1'} = '';
-    $selected{'LOG_VERB'}{'2'} = '';
-    $selected{'LOG_VERB'}{'3'} = '';
-    $selected{'LOG_VERB'}{'4'} = '';
-    $selected{'LOG_VERB'}{'5'} = '';
-    $selected{'LOG_VERB'}{'6'} = '';
-    $selected{'LOG_VERB'}{'7'} = '';
-    $selected{'LOG_VERB'}{'8'} = '';
-    $selected{'LOG_VERB'}{'9'} = '';
-    $selected{'LOG_VERB'}{'10'} = '';
-    $selected{'LOG_VERB'}{'11'} = '';
-    $selected{'LOG_VERB'}{$cgiparams{'LOG_VERB'}} = 'SELECTED';
+    $checked{'MSSFIX'}{$vpnsettings{'MSSFIX'}} = 'CHECKED';
+
+	# Split data ciphers
+	my @data_ciphers = split(/\|/, $vpnsettings{'DATACIPHERS'});
+
+	# Select the correct ones
+	$selected{'DATACIPHERS'} = ();
+	foreach my $cipher (@SUPPORTED_CIPHERS) {
+		$selected{'DATACIPHERS'}{$cipher} = grep(/^$cipher$/, @data_ciphers) ? "selected" : "";
+	}
+
+	# Routes
+	$vpnsettings{'ROUTES_PUSH'} =~ s/\|/\n/g;
+
+    $selected{'DCIPHER'}{'AES-256-GCM'} = '';
+    $selected{'DCIPHER'}{'AES-192-GCM'} = '';
+    $selected{'DCIPHER'}{'AES-128-GCM'} = '';
+    $selected{'DCIPHER'}{'CAMELLIA-256-CBC'} = '';
+    $selected{'DCIPHER'}{'CAMELLIA-192-CBC'} = '';
+    $selected{'DCIPHER'}{'CAMELLIA-128-CBC'} = '';
+    $selected{'DCIPHER'}{'AES-256-CBC'} = '';
+    $selected{'DCIPHER'}{'AES-192-CBC'} = '';
+    $selected{'DCIPHER'}{'AES-128-CBC'} = '';
+    $selected{'DCIPHER'}{'DES-EDE3-CBC'} = '';
+    $selected{'DCIPHER'}{'DESX-CBC'} = '';
+    $selected{'DCIPHER'}{'SEED-CBC'} = '';
+    $selected{'DCIPHER'}{'DES-EDE-CBC'} = '';
+    $selected{'DCIPHER'}{'CAST5-CBC'} = '';
+    $selected{'DCIPHER'}{'BF-CBC'} = '';
+    $selected{'DCIPHER'}{'DES-CBC'} = '';
+    $selected{'DCIPHER'}{$cgiparams{'DCIPHER'}} = 'SELECTED';
+
+    $selected{'DAUTH'}{'whirlpool'} = '';
+    $selected{'DAUTH'}{'SHA512'} = '';
+    $selected{'DAUTH'}{'SHA384'} = '';
+    $selected{'DAUTH'}{'SHA256'} = '';
+    $selected{'DAUTH'}{'SHA1'} = '';
+    $selected{'DAUTH'}{$cgiparams{'DAUTH'}} = 'SELECTED';
+
+    $checked{'TLSAUTH'}{'off'} = '';
+    $checked{'TLSAUTH'}{'on'} = '';
+    $checked{'TLSAUTH'}{$cgiparams{'TLSAUTH'}} = 'CHECKED';
 
     &Header::showhttpheaders();
     &Header::openpage($Lang::tr{'status ovpn'}, 1, '');
@@ -2705,290 +2711,358 @@ ADV_ERROR:
     &Header::opensection();
 
     print <<END;
-    <form method='post' enctype='multipart/form-data'>
-<table width='100%' border=0>
-	<tr>
-		<td colspan='4'><b>$Lang::tr{'dhcp-options'}</b></td>
-    </tr>
-    <tr>
-		<td width='25%'></td> <td width='20%'> </td><td width='25%'> </td><td width='30%'></td>
-    </tr>
-    <tr>
-		<td class='base'>Domain</td>
-        <td><input type='TEXT' name='DHCP_DOMAIN' value='$cgiparams{'DHCP_DOMAIN'}' size='30'  /></td>
-    </tr>
-    <tr>
-		<td class='base'>DNS</td>
-		<td><input type='TEXT' name='DHCP_DNS' value='$cgiparams{'DHCP_DNS'}' size='30' /></td>
-    </tr>
-    <tr>
-		<td class='base'>WINS</td>
-		<td><input type='TEXT' name='DHCP_WINS' value='$cgiparams{'DHCP_WINS'}' size='30' /></td>
-	</tr>
-    <tr>
-		<td colspan='4'><b>$Lang::tr{'ovpn routes push options'}</b></td>
-    </tr>
-    <tr>
-		<td class='base'>$Lang::tr{'ovpn routes push'}</td>
-		<td colspan='2'>
-		<textarea name='ROUTES_PUSH' cols='26' rows='6' wrap='off'>
+	    <form method='POST' enctype='multipart/form-data'>
+			<h6>$Lang::tr{'ovpn protocol settings'}</h6>
+
+			<table class="form">
+				<tr>
+					<td>$Lang::tr{'ovpn transport protocol'}</td>
+					<td>
+						<select name='DPROTOCOL'>
+							<option value='udp' $selected{'DPROTOCOL'}{'udp'}>UDP</option>
+							<option value='tcp' $selected{'DPROTOCOL'}{'tcp'}>TCP</option>
+						</select>
+					</td>
+				</tr>
+
+				<tr>
+					<td>$Lang::tr{'destination port'}</td>
+					<td>
+						<input type='number' name='DDEST_PORT' value='$vpnsettings{'DDEST_PORT'}' />
+					</td>
+				</tr>
+
+				<tr>
+					<td>$Lang::tr{'mtu'}</td>
+					<td>
+						<input type='number' name='DMTU' value='$vpnsettings{'DMTU'}' min="1280" max="9000" />
+					</td>
+				</tr>
+
+				<tr>
+					<td>mssfix</td>
+					<td>
+						<input type='checkbox' name='MSSFIX' $checked{'MSSFIX'}{'on'} />
+					</td>
+				</tr>
+
+				<tr>
+					<td>fragment</td>
+					<td>
+						<input type='TEXT' name='FRAGMENT' value='$vpnsettings{'FRAGMENT'}' />
+					</td>
+				</tr>
+			</table>
+
+			<h6>$Lang::tr{'ovpn crypto settings'}</h6>
+
+			<table class="form">
+				<tr>
+					<td>
+						$Lang::tr{'ovpn ciphers'}
+					</td>
+
+					<td>
+						<select name='DATACIPHERS' multiple required>
 END
-;
 
-if ($cgiparams{'ROUTES_PUSH'} ne '')
-{
-	print $cgiparams{'ROUTES_PUSH'};
-}
+	foreach my $cipher (@SUPPORTED_CIPHERS) {
+		my $name = $CIPHERS{$cipher} // $cipher;
 
-print <<END;
-</textarea></td>
-</tr>
-    </tr>
-</table>
-<hr size='1'>
-<table width='100%'>
-	<tr>
-		<td class='base'><b>$Lang::tr{'misc-options'}</b></td>
-	</tr>
+		print <<END;
+							<option value='$cipher' $selected{'DATACIPHERS'}{$cipher}>
+								$name
+							</option>
+END
+	}
 
-	<tr>
-		<td width='20%'></td> <td width='15%'> </td><td width='35%'> </td><td width='20%'></td><td width='35%'></td>
-	</tr>
+	print <<END;
+						</select>
+					</td>
+				</tr>
+
+				<tr>
+					<td>
+						$Lang::tr{'ovpn ha'}
+					</td>
+
+					<td>
+						<select name='DAUTH'>
+							<option value='whirlpool'		$selected{'DAUTH'}{'whirlpool'}>Whirlpool (512 $Lang::tr{'bit'})</option>
+							<option value='SHA512'			$selected{'DAUTH'}{'SHA512'}>SHA2 (512 $Lang::tr{'bit'})</option>
+							<option value='SHA384'			$selected{'DAUTH'}{'SHA384'}>SHA2 (384 $Lang::tr{'bit'})</option>
+							<option value='SHA256'			$selected{'DAUTH'}{'SHA256'}>SHA2 (256 $Lang::tr{'bit'})</option>
+							<option value='SHA1'			$selected{'DAUTH'}{'SHA1'}>SHA1 (160 $Lang::tr{'bit'}, $Lang::tr{'vpn weak'})</option>
+						</select>
+					</td>
+				</tr>
+
+				<tr>
+					<td>
+						$Lang::tr{'ovpn tls auth'}
+					</td>
+
+					<td>
+						<input type='checkbox' name='TLSAUTH' $checked{'TLSAUTH'}{'on'} />
+					</td>
+				</tr>
+
+				<tr>
+					<td>
+						$Lang::tr{'ovpn fallback cipher'}
+					</td>
+
+					<td>
+						<select name='DCIPHER'>
+							<option value='' $selected{'DCIPHER'}{''}>- $Lang::tr{'Disabled'} -</option>
+							<option value='AES-256-GCM' $selected{'DCIPHER'}{'AES-256-GCM'}>AES-GCM (256 $Lang::tr{'bit'})</option>
+							<option value='AES-192-GCM' $selected{'DCIPHER'}{'AES-192-GCM'}>AES-GCM (192 $Lang::tr{'bit'})</option>
+							<option value='AES-128-GCM' $selected{'DCIPHER'}{'AES-128-GCM'}>AES-GCM (128 $Lang::tr{'bit'})</option>
+							<option value='CAMELLIA-256-CBC' $selected{'DCIPHER'}{'CAMELLIA-256-CBC'}>CAMELLIA-CBC (256 $Lang::tr{'bit'})</option>
+							<option value='CAMELLIA-192-CBC' $selected{'DCIPHER'}{'CAMELLIA-192-CBC'}>CAMELLIA-CBC (192 $Lang::tr{'bit'})</option>
+							<option value='CAMELLIA-128-CBC' $selected{'DCIPHER'}{'CAMELLIA-128-CBC'}>CAMELLIA-CBC (128 $Lang::tr{'bit'})</option>
+							<option value='AES-256-CBC' $selected{'DCIPHER'}{'AES-256-CBC'}>AES-CBC (256 $Lang::tr{'bit'})</option>
+							<option value='AES-192-CBC' $selected{'DCIPHER'}{'AES-192-CBC'}>AES-CBC (192 $Lang::tr{'bit'})</option>
+							<option value='AES-128-CBC' $selected{'DCIPHER'}{'AES-128-CBC'}>AES-CBC (128 $Lang::tr{'bit'})</option>
+							<option value='SEED-CBC' $selected{'DCIPHER'}{'SEED-CBC'}>SEED-CBC (128 $Lang::tr{'bit'})</option>
+							<option value='DES-EDE3-CBC' $selected{'DCIPHER'}{'DES-EDE3-CBC'}>DES-EDE3-CBC (192 $Lang::tr{'bit'}, $Lang::tr{'vpn weak'})</option>
+							<option value='DESX-CBC' $selected{'DCIPHER'}{'DESX-CBC'}>DESX-CBC (192 $Lang::tr{'bit'}, $Lang::tr{'vpn weak'})</option>
+							<option value='DES-EDE-CBC' $selected{'DCIPHER'}{'DES-EDE-CBC'}>DES-EDE-CBC (128 $Lang::tr{'bit'}, $Lang::tr{'vpn weak'})</option>
+							<option value='BF-CBC' $selected{'DCIPHER'}{'BF-CBC'}>BF-CBC (128 $Lang::tr{'bit'}, $Lang::tr{'vpn weak'})</option>
+							<option value='CAST5-CBC' $selected{'DCIPHER'}{'CAST5-CBC'}>CAST5-CBC (128 $Lang::tr{'bit'}, $Lang::tr{'vpn weak'})</option>
+						</select>
+					</td>
+				</tr>
+
+				<tr>
+					<td></td>
+					<td>
+						$Lang::tr{'ovpn fallback cipher help'}
+					</td>
+				</tr>
+			</table>
+
+			<h6>$Lang::tr{'ovpn dhcp settings'}</h6>
+
+			<table class="form">
+				<tr>
+					<td>Domain</td>
+					<td>
+						<input type='TEXT' name='DHCP_DOMAIN' value='$vpnsettings{'DHCP_DOMAIN'}' size='30' />
+					</td>
+				</tr>
+				<tr>
+					<td>DNS</td>
+					<td>
+						<input type='TEXT' name='DHCP_DNS' value='$vpnsettings{'DHCP_DNS'}' size='30' />
+					</td>
+				</tr>
+				<tr>
+					<td>WINS</td>
+					<td>
+						<input type='TEXT' name='DHCP_WINS' value='$vpnsettings{'DHCP_WINS'}' size='30' />
+					</td>
+				</tr>
+			</table>
+
+			<h6>$Lang::tr{'ovpn routing settings'}</h6>
+
+			<table class="form">
+				<tr>
+					<td>$Lang::tr{'ovpn push default route'}</td>
+					<td>
+						<input type='checkbox' name='REDIRECT_GW_DEF1' $checked{'REDIRECT_GW_DEF1'}{'on'} />
+					</td>
+				</tr>
+
+				<tr>
+					<td>$Lang::tr{'ovpn routes push'}</td>
+					<td>
+						<textarea name='ROUTES_PUSH' cols='26' rows='6' wrap='off'>$vpnsettings{'ROUTES_PUSH'}</textarea>
+					</td>
+				</tr>
+			</table>
+
+			<h6>$Lang::tr{'ovpn misc settings'}</h6>
+
+			<table class="form">
+				<tr>
+					<td>Max-Clients</td>
+					<td>
+						<input type='text' name='MAX_CLIENTS' value='$vpnsettings{'MAX_CLIENTS'}' />
+					</td>
+				</tr>
+
+				<tr class="action">
+					<td colspan="2">
+						<input type='submit' name='ACTION' value='$Lang::tr{'save-adv-options'}' />
+						<input type='submit' name='ACTION' value='$Lang::tr{'cancel-adv-options'}' />
+					</td>
+				</tr>
+			</table>
+END
 
-	<tr>
-		<td class='base'>Client-To-Client</td>
-		<td><input type='checkbox' name='CLIENT2CLIENT' $checked{'CLIENT2CLIENT'}{'on'} /></td>
-	</tr>
+    &Header::closesection();
+    &Header::closebigbox();
 
-	<tr>
-		<td class='base'>Redirect-Gateway def1</td>
-		<td><input type='checkbox' name='REDIRECT_GW_DEF1' $checked{'REDIRECT_GW_DEF1'}{'on'} /></td>
-	</tr>
+    &Header::closepage();
+    exit(0);
 
-    <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'comp-lzo'}</td>
-        <td><input type='checkbox' name='DCOMPLZO' $checked{'DCOMPLZO'}{'on'} /></td>
-        <td>$Lang::tr{'openvpn default'}: off <font color='red'>($Lang::tr{'attention'} exploitable via Voracle)</font></td>
-    </tr>
 
-	<tr>
-		<td class='base'>$Lang::tr{'ovpn add conf'}</td>
-		<td><input type='checkbox' name='ADDITIONAL_CONFIGS' $checked{'ADDITIONAL_CONFIGS'}{'on'} /></td>
-		<td>$Lang::tr{'openvpn default'}: off</td>
-	</tr>
+# Add, delete or edit CCD net
 
-	<tr>
-		<td class='base'>mssfix</td>
-		<td><input type='checkbox' name='MSSFIX' $checked{'MSSFIX'}{'on'} /></td>
-		<td>$Lang::tr{'openvpn default'}: off</td>
-	</tr>
+} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'ccd net'} ||
+		$cgiparams{'ACTION'} eq "ccd-add" ||
+		$cgiparams{'ACTION'} eq "ccd-delete" ||
+		$cgiparams{'ACTION'} eq "ccd-edit" ||
+		$cgiparams{'ACTION'} eq 'ccd-edit-save'){
+	&Header::showhttpheaders();
 
-	<tr>
-		<td class='base'>fragment <br></td>
-		<td><input type='TEXT' name='FRAGMENT' value='$cgiparams{'FRAGMENT'}' size='10' /></td>
-	</tr>
+	&Header::openpage($Lang::tr{'ccd net'}, 1, '');
 
+	&Header::openbigbox('100%', 'LEFT', '', '');
 
-	<tr>
-		<td class='base'>Max-Clients</td>
-		<td><input type='text' name='MAX_CLIENTS' value='$cgiparams{'MAX_CLIENTS'}' size='10' /></td>
-	</tr>
-	<tr>
-		<td class='base'>Keepalive <br />
-		(ping/ping-restart)</td>
-		<td><input type='TEXT' name='KEEPALIVE_1' value='$cgiparams{'KEEPALIVE_1'}' size='10' /></td>
-		<td><input type='TEXT' name='KEEPALIVE_2' value='$cgiparams{'KEEPALIVE_2'}' size='10' /></td>
-	</tr>
-</table>
+	# Delete?
+	if ($cgiparams{'ACTION'} eq "ccd-delete") {
+		$errormessage = &delccdnet($cgiparams{'name'});
 
-<hr size='1'>
-<table width='100%'>
-    <tr>
-	<td class='base'><b>$Lang::tr{'log-options'}</b></td>
-    </tr>
-    <tr>
-	<td width='20%'></td> <td width='30%'> </td><td width='25%'> </td><td width='25%'></td>
-    </tr>
+	# Save after edit?
+	} elsif ($cgiparams{'ACTION'} eq 'ccd-edit-save') {
+		$errormessage = &modccdnet($cgiparams{'subnet'}, $cgiparams{'name'});
 
-    <tr><td class='base'>VERB</td>
-        <td><select name='LOG_VERB'>
-			<option value='0'  $selected{'LOG_VERB'}{'0'}>0</option>
-			<option value='1'  $selected{'LOG_VERB'}{'1'}>1</option>
-			<option value='2'  $selected{'LOG_VERB'}{'2'}>2</option>
-			<option value='3'  $selected{'LOG_VERB'}{'3'}>3</option>
-			<option value='4'  $selected{'LOG_VERB'}{'4'}>4</option>
-			<option value='5'  $selected{'LOG_VERB'}{'5'}>5</option>
-			<option value='6'  $selected{'LOG_VERB'}{'6'}>6</option>
-			<option value='7'  $selected{'LOG_VERB'}{'7'}>7</option>
-			<option value='8'  $selected{'LOG_VERB'}{'8'}>8</option>
-			<option value='9'  $selected{'LOG_VERB'}{'9'}>9</option>
-			<option value='10' $selected{'LOG_VERB'}{'10'}>10</option>
-			<option value='11' $selected{'LOG_VERB'}{'11'}>11</option>
-	</td></select>
-    </table>
+		# Clear inputs
+		if ($errormessage eq "") {
+			$cgiparams{"name"} = "";
+			$cgiparams{"subnet"} = "";
+		}
 
-<hr size='1'>
-END
+	# Add?
+	} elsif ($cgiparams{'ACTION'} eq "ccd-add") {
+		$errormessage = &addccdnet($cgiparams{'name'}, $cgiparams{'subnet'});
 
-if ( -e "/var/run/openvpn.pid"){
-print"	<br><b><font color='#990000'>$Lang::tr{'attention'}:</b></font><br>
-		$Lang::tr{'server restart'}<br><br>
-		<hr>";
-	print<<END;
-<table width='100%'>
-<tr>
-    <td>&nbsp;</td>
-    <td allign='center'><input type='submit' name='ACTION' value='$Lang::tr{'save-adv-options'}' disabled='disabled' /></td>
-    <td allign='center'><input type='submit' name='ACTION' value='$Lang::tr{'cancel-adv-options'}' /></td>
-    <td>&nbsp;</td>
-</tr>
-</table>
-</form>
-END
-;
+		# Clear inputs
+		if ($errormessage eq "") {
+			$cgiparams{"name"} = "";
+			$cgiparams{"subnet"} = "";
+		}
+	}
 
+	&Header::errorbox($errormessage);
 
-}else{
+	my %ccdconfhash = ();
+	&General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
 
-	print<<END;
-<table width='100%'>
-<tr>
-    <td>&nbsp;</td>
-    <td allign='center'><input type='submit' name='ACTION' value='$Lang::tr{'save-adv-options'}' /></td>
-    <td allign='center'><input type='submit' name='ACTION' value='$Lang::tr{'cancel-adv-options'}' /></td>
-    <td>&nbsp;</td>
-</tr>
-</table>
-</form>
-END
-;
-}
-    &Header::closebox();
-#    print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
-    &Header::closebigbox();
-    &Header::closepage();
-    exit(0);
+	&Header::opensection();
+	print <<END;
+		<table class="tbl">
+			<tr>
+				<th>
+					$Lang::tr{'ccd name'}
+				</th>
 
+				<th>
+					$Lang::tr{'network'}
+				</th>
 
-# A.Marx CCD   Add,delete or edit CCD net
+				<th>
+					$Lang::tr{'ccd used'}
+				</th>
 
-} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'ccd net'} ||
-		$cgiparams{'ACTION'} eq $Lang::tr{'ccd add'} ||
-		$cgiparams{'ACTION'} eq "kill" ||
-		$cgiparams{'ACTION'} eq "edit" ||
-		$cgiparams{'ACTION'} eq 'editsave'){
-	&Header::showhttpheaders();
-	&Header::openpage($Lang::tr{'ccd net'}, 1, '');
-	&Header::openbigbox('100%', 'LEFT', '', '');
+				<th colspan="2"></th>
+			</tr>
+END
 
-	if ($cgiparams{'ACTION'} eq "kill"){
-		&delccdnet($cgiparams{'net'});
-	}
+	foreach my $key (sort { uc($ccdconfhash{$a}[0]) cmp uc($ccdconfhash{$b}[0]) } keys %ccdconfhash) {
+		my $name   = $ccdconfhash{$key}[0];
+		my $subnet = $ccdconfhash{$key}[1];
 
-	if ($cgiparams{'ACTION'} eq 'editsave'){
-		my ($a,$b) =split (/\|/,$cgiparams{'ccdname'});
-		if ( $a ne $b){ &modccdnet($a,$b);}
-		$cgiparams{'ccdname'}='';
-		$cgiparams{'ccdsubnet'}='';
-	}
+		my $ccdhosts = scalar &get_addresses_in_use($subnet);
+		my $maxhosts = &ccdmaxclients($subnet);
 
-	if ($cgiparams{'ACTION'} eq $Lang::tr{'ccd add'}) {
-		&addccdnet($cgiparams{'ccdname'},$cgiparams{'ccdsubnet'});
-	}
-	if ($errormessage) {
-	    &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
-	    print "<class name='base'>$errormessage";
-	    print "&nbsp;</class>";
-	    &Header::closebox();
+		print <<END;
+			<tr>
+				<th scope="row">
+					$name
+				</th>
+
+				<td class="text-center">
+					$subnet
+				</td>
+
+				<td class="text-center">
+					${ccdhosts}/${maxhosts}
+				</td>
+
+				<td class="text-center">
+					<form method='post' />
+						<input type='image' src='/images/edit.gif' align='middle'
+							alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' />
+						<input type='hidden' name='ACTION' value='ccd-edit'/>
+						<input type='hidden' name='name' value='$name' />
+						<input type='hidden' name='subnet' value='$subnet' />
+					</form>
+				</td>
+
+				<td class="text-center">
+					<form method='post' />
+						<input type='hidden' name='ACTION' value='ccd-delete'/>
+						<input type='hidden' name='name' value='$name' />
+						<input type='image' src='/images/delete.gif' align='middle'
+							alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' />
+					</form>
+				</td>
+			</tr>
+END
 	}
-if ($cgiparams{'ACTION'} eq "edit"){
+	print "</table>";
+	&Header::closesection();
+
+	&Header::openbox('100%', 'LEFT',
+		($cgiparams{'ACTION'} eq "ccd-edit") ? $Lang::tr{'ccd modify'} : $Lang::tr{'ccd add'});
 
-	&Header::openbox('100%', 'LEFT', $Lang::tr{'ccd modify'});
+	# The subnet cannot be edited
+	my $readonly = ($cgiparams{'ACTION'} eq "ccd-edit") ? "readonly" : "";
+	my $action   = ($cgiparams{'ACTION'} eq "ccd-edit") ? "ccd-edit-save" : "ccd-add";
 
 	print <<END;
-    <table width='100%' border='0'>
-    <tr><form method='post'>
-	<td width='10%' nowrap='nowrap'>$Lang::tr{'ccd name'}:</td><td><input type='TEXT' name='ccdname' value='$cgiparams{'ccdname'}' /></td>
-	<td width='8%'>$Lang::tr{'ccd subnet'}:</td><td><input type='TEXT' name='ccdsubnet' value='$cgiparams{'ccdsubnet'}' readonly='readonly' /></td></tr>
-	<tr><td colspan='4' align='right'><hr><input type='submit' value='$Lang::tr{'save'}' /><input type='hidden' name='ACTION' value='editsave'/>
-	<input type='hidden' name='ccdname' value='$cgiparams{'ccdname'}'/><input type='submit' value='$Lang::tr{'cancel'}' />
-	</td></tr>
-	</table></form>
+		<form method='post'>
+			<table class="form">
+				<tr>
+					<td>$Lang::tr{'ccd name'}</td>
+					<td>
+						<input type='TEXT' name='name' value='$cgiparams{'name'}' />
+					</td>
+				</tr>
+
+				<tr>
+					<td>$Lang::tr{'ccd subnet'}</td>
+					<td>
+						<input type='TEXT' name='subnet' value='$cgiparams{'subnet'}'
+							$readonly />
+					</td>
+				</tr>
+
+				<tr class="action">
+					<td colspan="2">
+						<input type='hidden' name='ACTION' value='$action' />
+						<input type='submit' value='$Lang::tr{'save'}' />
+					</td>
+				</tr>
+			</table>
+		</form>
 END
-;
 	&Header::closebox();
 
-	&Header::openbox('100%', 'LEFT',$Lang::tr{'ccd net'} );
-	print <<END;
-    <table width='100%' border='0'  cellpadding='0' cellspacing='1'>
-    <tr>
-	<td class='boldbase' align='center'><b>$Lang::tr{'ccd name'}</td><td class='boldbase' align='center'><b>$Lang::tr{'network'}</td><td class='boldbase' width='15%' align='center'><b>$Lang::tr{'ccd used'}</td><td width='3%'></td><td width='3%'></td></tr>
-END
-;
-}
-else{
-	if (! -e "/var/run/openvpn.pid"){
-	&Header::openbox('100%', 'LEFT', $Lang::tr{'ccd add'});
 	print <<END;
-	    <table width='100%' border='0'>
-	    <tr><form method='post'>
-		<td colspan='4'>$Lang::tr{'ccd hint'}<br><br></td></tr>
-		<tr>
-		<td width='10%' nowrap='nwrap'>$Lang::tr{'ccd name'}:</td><td><input type='TEXT' name='ccdname' value='$cgiparams{'ccdname'}' /></td>
-		<td width='8%'>$Lang::tr{'ccd subnet'}:</td><td><input type='TEXT' name='ccdsubnet' value='$cgiparams{'ccdsubnet'}' /></td></tr>
-		<tr><td colspan=4><hr /></td></tr><tr>
-		<td colspan='4' align='right'><input type='hidden' name='ACTION' value='$Lang::tr{'ccd add'}' /><input type='submit' value='$Lang::tr{'add'}' /><input type='hidden' name='DOVPN_SUBNET' value='$cgiparams{'DOVPN_SUBNET'}'/></td></tr>
-		</table></form>
+		<div class="text-center">
+			<a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a>
+		</div>
 END
 
-	&Header::closebox();
-}
-	&Header::openbox('100%', 'LEFT',$Lang::tr{'ccd net'} );
-	if ( -e "/var/run/openvpn.pid"){
-		print "<b>$Lang::tr{'attention'}:</b><br>";
-		print "$Lang::tr{'ccd noaddnet'}<br><hr>";
-	}
-
-    print <<END;
-    <table width='100%' cellpadding='0' cellspacing='1'>
-    <tr>
-	<td class='boldbase' align='center' nowrap='nowrap' width='20%'><b>$Lang::tr{'ccd name'}</td><td class='boldbase' align='center' width='8%'><b>$Lang::tr{'network'}</td><td class='boldbase' width='8%' align='center' nowrap='nowrap'><b>$Lang::tr{'ccd used'}</td><td width='1%' align='center'></td><td width='1%' align='center'></td></tr>
-END
-;
-}
-	my %ccdconfhash=();
-	&General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
-	my @ccdconf=();
-	my $count=0;
-	foreach my $key (sort { uc($ccdconfhash{$a}[0]) cmp uc($ccdconfhash{$b}[0]) } keys %ccdconfhash) {
-		@ccdconf=($ccdconfhash{$key}[0],$ccdconfhash{$key}[1]);
-		$count++;
-		my $ccdhosts = &hostsinnet($ccdconf[0]);
-		if ($count % 2){ print" <tr bgcolor='$color{'color22'}'>";}
-		else{            print" <tr bgcolor='$color{'color20'}'>";}
-		print"<td>$ccdconf[0]</td><td align='center'>$ccdconf[1]</td><td align='center'>$ccdhosts/".(&ccdmaxclients($ccdconf[1])+1)."</td><td>";
-        print <<END;
-		<form method='post' />
-		<input type='image' src='/images/edit.gif' align='middle' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' />
-		<input type='hidden' name='ACTION' value='edit'/>
-		<input type='hidden' name='ccdname' value='$ccdconf[0]' />
-		<input type='hidden' name='ccdsubnet' value='$ccdconf[1]' />
-		</form></td>
-		<form method='post' />
-		<td><input type='hidden' name='ACTION' value='kill'/>
-		<input type='hidden' name='number' value='$count' />
-		<input type='hidden' name='net' value='$ccdconf[0]' />
-		<input type='image' src='/images/delete.gif' align='middle' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' /></form></td></tr>
-END
-;
-	}
-	print "</table></form>";
-	&Header::closebox();
-	print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
 	&Header::closebigbox();
 	&Header::closepage();
-	exit(0);
 
-#END CCD
+	exit(0);
 
 ###
 ### Openvpn Connections Statistics
@@ -2997,111 +3071,136 @@ END
 	&Header::showhttpheaders();
 	&Header::openpage($Lang::tr{'ovpn con stat'}, 1, '');
 	&Header::openbigbox('100%', 'LEFT', '', '');
-    &Header::openbox('100%', 'LEFT', $Lang::tr{'ovpn con stat'});
 
-#
-#	<td><b>$Lang::tr{'protocol'}</b></td>
-# protocol temp removed
-    print <<END;
-    <table width='100%' cellpadding='2' cellspacing='0' class='tbl'>
-    <tr>
-	<th><b>$Lang::tr{'common name'}</b></th>
-	<th><b>$Lang::tr{'real address'}</b></th>
-	<th><b>$Lang::tr{'country'}</b></th>
-	<th><b>$Lang::tr{'virtual address'}</b></th>
-	<th><b>$Lang::tr{'loged in at'}</b></th>
-	<th><b>$Lang::tr{'bytes sent'}</b></th>
-	<th><b>$Lang::tr{'bytes received'}</b></th>
-	<th><b>$Lang::tr{'last activity'}</b></th>
-    </tr>
+	&Header::opensection();
+
+	print <<END;
+		<table class='tbl'>
+			<tr>
+				<th>$Lang::tr{'common name'}</th>
+				<th>$Lang::tr{'real address'}</th>
+				<th>$Lang::tr{'country'}</th>
+				<th>$Lang::tr{'virtual address'}</th>
+				<th>$Lang::tr{'loged in at'}</th>
+				<th>$Lang::tr{'bytes sent'}</th>
+				<th>$Lang::tr{'bytes received'}</th>
+				<th>$Lang::tr{'last activity'}</th>
+			</tr>
 END
-;
-	my $filename = "/var/run/ovpnserver.log";
-	open(FILE, $filename) or die 'Unable to open config file.';
+
+	open(FILE, "/usr/local/bin/openvpnctrl rw log |") or die "Unable to open $RW_STATUS: $!";
 	my @current = <FILE>;
 	close(FILE);
-	my @users =();
+
+	my @users = ();
 	my $status;
 	my $uid = 0;
-	my $cn;
 	my @match = ();
-	my $proto = "udp";
-	my $address;
 	my %userlookup = ();
-	foreach my $line (@current)
-	{
+
+	foreach my $line (@current) {
 	    chomp($line);
-	    if ( $line =~ /^Updated,(.+)/){
-		@match = split( /^Updated,(.+)/, $line);
-		$status = $match[1];
-	    }
-#gian
-	    if ( $line =~ /^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/) {
-		@match = split(m/^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/, $line);
-		if ($match[1] ne "Common Name") {
-	    	    $cn = $match[1];
-		    $userlookup{$match[2]} = $uid;
-		    $users[$uid]{'CommonName'} = $match[1];
-		    $users[$uid]{'RealAddress'} = $match[2];
-		    $users[$uid]{'BytesReceived'} = &sizeformat($match[3]);
-		    $users[$uid]{'BytesSent'} = &sizeformat($match[4]);
-		    $users[$uid]{'Since'} = $match[5];
-		    $users[$uid]{'Proto'} = $proto;
-
-		    # get country code for "RealAddress"...
-		    my $ccode = &Location::Functions::lookup_country_code((split ':', $users[$uid]{'RealAddress'})[0]);
-		    my $flag_icon = &Location::Functions::get_flag_icon($ccode);
-		    $users[$uid]{'Country'} = "<a href='country.cgi#$ccode'><img src='$flag_icon' border='0' align='absmiddle' alt='$ccode' title='$ccode' /></a>";
-		    $uid++;
-		}
-	    }
-	    if ( $line =~ /^(\d+\.\d+\.\d+\.\d+),(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(.+)/) {
-		@match = split(m/^(\d+\.\d+\.\d+\.\d+),(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(.+)/, $line);
-		if ($match[1] ne "Virtual Address") {
-		    $address = $match[3];
-		    #find the uid in the lookup table
-		    $uid = $userlookup{$address};
-		    $users[$uid]{'VirtualAddress'} = $match[1];
-		    $users[$uid]{'LastRef'} = $match[4];
+
+	    if ($line =~ /^Updated,(.+)/) {
+			@match = split(/^Updated,(.+)/, $line);
+			$status = $match[1];
+
+		} elsif ( $line =~ /^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/) {
+			@match = split(m/^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/, $line);
+
+			# Skip the header
+			next if ($match[1] eq "Common Name");
+
+			$userlookup{$match[2]} = $uid;
+			$users[$uid]{'CommonName'} = $match[1];
+			$users[$uid]{'RealAddress'} = $match[2];
+			$users[$uid]{'BytesReceived'} = &General::formatBytes($match[3]);
+			$users[$uid]{'BytesSent'} = &General::formatBytes($match[4]);
+			$users[$uid]{'Since'} = $match[5];
+
+			my $address = (split ':', $users[$uid]{'RealAddress'})[0];
+			$users[$uid]{'Country'} = &Location::Functions::lookup_country_code($address);
+			$uid++;
+
+		} elsif ($line =~ /^(\d+\.\d+\.\d+\.\d+),(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(.+)/) {
+			@match = split(m/^(\d+\.\d+\.\d+\.\d+),(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(.+)/, $line);
+
+			# Skip the header
+			next if ($match[1] eq "Virtual Address");
+
+			my $address = $match[3];
+			#find the uid in the lookup table
+			$uid = $userlookup{$address};
+			$users[$uid]{'VirtualAddress'} = $match[1];
+			$users[$uid]{'LastRef'} = $match[4];
 		}
-	    }
 	}
-	my $user2 = @users;
-	if ($user2 >= 1){
-		for (my $idx = 1; $idx <= $user2; $idx++){
-						if ($idx % 2) {
-							print "<tr>";
-							$col="bgcolor='$color{'color22'}'";
-						} else {
-							print "<tr>";
-							$col="bgcolor='$color{'color20'}'";
-						}
-						print "<td align='left' $col>$users[$idx-1]{'CommonName'}</td>";
-						print "<td align='left' $col>$users[$idx-1]{'RealAddress'}</td>";
-						print "<td align='center' $col>$users[$idx-1]{'Country'}</td>";
-						print "<td align='center' $col>$users[$idx-1]{'VirtualAddress'}</td>";
-						print "<td align='left' $col>$users[$idx-1]{'Since'}</td>";
-						print "<td align='left' $col>$users[$idx-1]{'BytesSent'}</td>";
-						print "<td align='left' $col>$users[$idx-1]{'BytesReceived'}</td>";
-						print "<td align='left' $col>$users[$idx-1]{'LastRef'}</td>";
-			}
+
+	foreach my $id (keys @users) {
+		my $user = $users[$id];
+
+		my $flag_icon = &Location::Functions::get_flag_icon($user->{"Country"});
+
+		print <<END;
+			<tr>
+				<th scope="row">
+					$user->{"CommonName"}
+				</th>
+
+				<td class="text-center">
+					$user->{"RealAddress"}
+				</td>
+
+				<td class="text-center">
+					<a href="country.cgi#$user->{"Country"}">
+						<img src="$flag_icon" border='0' align='absmiddle'
+							alt='$user->{"Country"}' title='$user->{"Country"}' />
+					</a>
+				</td>
+
+				<td class="text-center">
+					$user->{"VirtualAddress"}
+				</td>
+
+				<td class="text-center">
+					$user->{"Since"}
+				</td>
+
+				<td class="text-right">
+					$user->{"BytesSent"}
+				</td>
+
+				<td class="text-right">
+					$user->{"BytesReceived"}
+				</td>
+
+				<td class="text-right">
+					$user->{"LastRef"}
+				</td>
+			</tr>
+END
 	}
 
-	print "</table>";
-	print <<END;
-	<table width='100%' border='0' cellpadding='2' cellspacing='0'>
-	<tr><td></td></tr>
-	<tr><td></td></tr>
-	<tr><td></td></tr>
-	<tr><td></td></tr>
-	<tr><td align='center' >$Lang::tr{'the statistics were last updated at'} <b>$status</b></td></tr>
+print <<END;
 	</table>
+
+	<p class="text-center">
+		$Lang::tr{'the statistics were last updated at'} <b>$status</b>
+	</p>
 END
 ;
-	&Header::closebox();
-	print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
+
+	&Header::closesection();
+
+	print <<END;
+		<p class="text-center">
+			<a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a>
+		</p>
+END
+
 	&Header::closebigbox();
 	&Header::closepage();
+
 	exit(0);
 
 ###
@@ -3127,8 +3226,6 @@ END
 ###
 
 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'toggle enable disable'}) {
-
-    &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
 
     if ($confighash{$cgiparams{'KEY'}}) {
@@ -3153,28 +3250,7 @@ END
 	$errormessage = $Lang::tr{'invalid key'};
     }
 
-###
-### Restart connection
-###
-} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'restart'}) {
-    &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
-    &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
-
-    if ($confighash{$cgiparams{'KEY'}}) {
-#	if ($vpnsettings{'ENABLED'} eq 'on' ||
-#	    $vpnsettings{'ENABLED_BLUE'} eq 'on') {
-#	    system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'});
-#	}
-    } else {
-	$errormessage = $Lang::tr{'invalid key'};
-    }
-
-###
-# m.a.d net2net
-###
-
 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'add'} && $cgiparams{'TYPE'} eq '') {
-	&General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
 	&Header::showhttpheaders();
 	&Header::openpage($Lang::tr{'ovpn'}, 1, '');
 	&Header::openbigbox('100%', 'LEFT', '', '');
@@ -3219,10 +3295,6 @@ END
 	&Header::closepage();
 	exit (0);
 
-###
-# m.a.d net2net
-###
-
 }  elsif (($cgiparams{'ACTION'} eq $Lang::tr{'add'}) && ($cgiparams{'TYPE'} eq 'net2net')){
 
 	my @firen2nconf;
@@ -3294,10 +3366,6 @@ END
 		goto N2N_ERROR;
 	}
 
-###
-# m.a.d net2net
-###
-
  if ($cgiparams{'n2nname'} ne ''){
 
   $uplconffilename2 = "$cgiparams{'n2nname'}.conf";
@@ -3397,10 +3465,6 @@ $n2nauth[1] =~ s/\n|\r//g;
 chomp ($complzoactive);
 chomp ($mssfixactive);
 
-###
-# m.a.d net2net
-###
-
 ###
 # Check if there is no other entry with this name
 ###
@@ -3558,20 +3622,12 @@ if ($confighash{$cgiparams{'KEY'}}) {
 		$errormessage = $Lang::tr{'invalid key'};
    }
 
-
-###
-# m.a.d net2net
-###
-
-
 ###
 ### Adding a new connection
 ###
 } elsif (($cgiparams{'ACTION'} eq $Lang::tr{'add'}) ||
 	 ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) ||
 	 ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'ADVANCED'} eq '')) {
-
-    &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
     &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
 
@@ -3613,7 +3669,7 @@ if ($confighash{$cgiparams{'KEY'}}) {
 	} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) {
 	$cgiparams{'REMARK'} = &Header::cleanhtml($cgiparams{'REMARK'});
 
-#A.Marx CCD check iroute field and convert it to decimal
+# CCD check iroute field and convert it to decimal
 if ($cgiparams{'TYPE'} eq 'host') {
 	my @temp=();
 	my %ccdroutehash=();
@@ -3667,19 +3723,19 @@ if ($cgiparams{'TYPE'} eq 'host') {
 			}
 
 			#check for existing network IP's
-			if (&General::IpInSubnet ($ip,$netsettings{GREEN_NETADDRESS},$netsettings{GREEN_NETMASK}) && $netsettings{GREEN_NETADDRESS} ne '0.0.0.0')
+			if (&General::IpInSubnet ($ip,$Network::ethernet{GREEN_NETADDRESS},$Network::ethernet{GREEN_NETMASK}) && $Network::ethernet{GREEN_NETADDRESS} ne '0.0.0.0')
 			{
 				$errormessage=$Lang::tr{'ccd err green'};
 				goto VPNCONF_ERROR;
-			}elsif(&General::IpInSubnet ($ip,$netsettings{RED_NETADDRESS},$netsettings{RED_NETMASK}) && $netsettings{RED_NETADDRESS} ne '0.0.0.0')
+			}elsif(&General::IpInSubnet ($ip,$Network::ethernet{RED_NETADDRESS},$Network::ethernet{RED_NETMASK}) && $Network::ethernet{RED_NETADDRESS} ne '0.0.0.0')
 			{
 				$errormessage=$Lang::tr{'ccd err red'};
 				goto VPNCONF_ERROR;
-			}elsif(&General::IpInSubnet ($ip,$netsettings{BLUE_NETADDRESS},$netsettings{BLUE_NETMASK}) && $netsettings{BLUE_NETADDRESS} ne '0.0.0.0' && $netsettings{BLUE_NETADDRESS} gt '')
+			}elsif(&General::IpInSubnet ($ip,$Network::ethernet{BLUE_NETADDRESS},$Network::ethernet{BLUE_NETMASK}) && $Network::ethernet{BLUE_NETADDRESS} ne '0.0.0.0' && $Network::ethernet{BLUE_NETADDRESS} gt '')
 			{
 				$errormessage=$Lang::tr{'ccd err blue'};
 				goto VPNCONF_ERROR;
-			}elsif(&General::IpInSubnet ($ip,$netsettings{ORANGE_NETADDRESS},$netsettings{ORANGE_NETMASK}) && $netsettings{ORANGE_NETADDRESS} ne '0.0.0.0' && $netsettings{ORANGE_NETADDRESS} gt '' )
+			}elsif(&General::IpInSubnet ($ip,$Network::ethernet{ORANGE_NETADDRESS},$Network::ethernet{ORANGE_NETMASK}) && $Network::ethernet{ORANGE_NETADDRESS} ne '0.0.0.0' && $Network::ethernet{ORANGE_NETADDRESS} gt '' )
 			{
 				$errormessage=$Lang::tr{'ccd err orange'};
 				goto VPNCONF_ERROR;
@@ -3724,22 +3780,20 @@ if ($cgiparams{'TYPE'} eq 'host') {
 	$ccdroute2hash{$keypoint}[0]=$cgiparams{'NAME'};
 	if ($cgiparams{'IFROUTE'} eq ''){$cgiparams{'IFROUTE'} = $Lang::tr{'ccd none'};}
 	@temp = split(/\|/,$cgiparams{'IFROUTE'});
-	my %ownnet=();
-	&General::readhash("${General::swroot}/ethernet/settings", \%ownnet);
 	foreach $val (@temp){
 		chomp($val);
 		$val=~s/\s*$//g;
 		if ($val eq $Lang::tr{'green'})
 		{
-			$val=$ownnet{GREEN_NETADDRESS}."/".$ownnet{GREEN_NETMASK};
+			$val=$Network::ethernet{GREEN_NETADDRESS}."/".$Network::ethernet{GREEN_NETMASK};
 		}
 		if ($val eq $Lang::tr{'blue'})
 		{
-			$val=$ownnet{BLUE_NETADDRESS}."/".$ownnet{BLUE_NETMASK};
+			$val=$Network::ethernet{BLUE_NETADDRESS}."/".$Network::ethernet{BLUE_NETMASK};
 		}
 		if ($val eq $Lang::tr{'orange'})
 		{
-			$val=$ownnet{ORANGE_NETADDRESS}."/".$ownnet{ORANGE_NETMASK};
+			$val=$Network::ethernet{ORANGE_NETADDRESS}."/".$Network::ethernet{ORANGE_NETMASK};
 		}
 		my ($ip,$cidr) = split (/\//, $val);
 
@@ -3779,9 +3833,6 @@ if ($cgiparams{'TYPE'} eq 'host') {
 	}
 }
 
-#CCD End
-
-
 	if ($cgiparams{'TYPE'} !~ /^(host|net)$/) {
 		$errormessage = $Lang::tr{'connection type is invalid'};
 		if ($cgiparams{'TYPE'} eq 'net') {
@@ -3820,10 +3871,6 @@ if ($cgiparams{'TYPE'} eq 'host') {
 		goto VPNCONF_ERROR;
 	}
 
-###
-# m.a.d net2net
-###
-
 if ($cgiparams{'TYPE'} eq 'net') {
 	if ($cgiparams{'DEST_PORT'} eq  $vpnsettings{'DDEST_PORT'}) {
 			$errormessage = $Lang::tr{'openvpn destination port used'};
@@ -3876,21 +3923,21 @@ if ($cgiparams{'TYPE'} eq 'net') {
 	    goto VPNCONF_ERROR;
     }
 
-    if ( &validdotmask ($cgiparams{'LOCAL_SUBNET'}))  {
+    if (!&Network::check_subnet($cgiparams{'LOCAL_SUBNET'}))  {
 		  $errormessage = $Lang::tr{'openvpn prefix local subnet'};
 		  unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
 	    rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
 		  goto VPNCONF_ERROR;
 		}
 
-    if ( &validdotmask ($cgiparams{'OVPN_SUBNET'}))  {
+    if (!&Network::check_subnet($cgiparams{'OVPN_SUBNET'}))  {
 		  $errormessage = $Lang::tr{'openvpn prefix openvpn subnet'};
 		  unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
 	    rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
 		  goto VPNCONF_ERROR;
 		}
 
-    if ( &validdotmask ($cgiparams{'REMOTE_SUBNET'}))  {
+    if (!&Network::check_subnet($cgiparams{'REMOTE_SUBNET'}))  {
 		  $errormessage = $Lang::tr{'openvpn prefix remote subnet'};
 		  unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
 	    rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
@@ -3922,11 +3969,6 @@ if ($cgiparams{'TYPE'} eq 'net') {
 	}
 }
 
-#	if (($cgiparams{'TYPE'} eq 'net') && ($cgiparams{'SIDE'} !~ /^(left|right)$/)) {
-#	    $errormessage = $Lang::tr{'ipfire side is invalid'};
-#	    goto VPNCONF_ERROR;
-#	}
-
 	# Check if there is no other entry with this name
 	if (! $cgiparams{'KEY'}) {
 	    foreach my $key (keys %confighash) {
@@ -4008,26 +4050,12 @@ if ($cgiparams{'TYPE'} eq 'net') {
 		}
 	}
 
-	if ($cgiparams{'ENABLED'} !~ /^(on|off)$/) {
-	    $errormessage = $Lang::tr{'invalid input'};
-	    goto VPNCONF_ERROR;
-	}
-	if ($cgiparams{'EDIT_ADVANCED'} !~ /^(on|off)$/) {
+	if ($cgiparams{'ENABLED'} !~ /^(on|off|)$/) {
 	    $errormessage = $Lang::tr{'invalid input'};
 	    goto VPNCONF_ERROR;
 	}
 
-#fixplausi
-	if ($cgiparams{'AUTH'} eq 'psk')  {
-#	    if (! length($cgiparams{'PSK'}) ) {
-#		$errormessage = $Lang::tr{'pre-shared key is too short'};
-#		goto VPNCONF_ERROR;
-#	    }
-#	    if ($cgiparams{'PSK'} =~ /['",&]/) {
-#		$errormessage = $Lang::tr{'invalid characters found in pre-shared key'};
-#		goto VPNCONF_ERROR;
-#	    }
-	} elsif ($cgiparams{'AUTH'} eq 'certreq') {
+	if ($cgiparams{'AUTH'} eq 'certreq') {
 	    if ($cgiparams{'KEY'}) {
 		$errormessage = $Lang::tr{'cant change certificates'};
 		goto VPNCONF_ERROR;
@@ -4056,7 +4084,7 @@ if ($cgiparams{'TYPE'} eq 'net') {
 		$errormessage = "$Lang::tr{'openssl produced an error'}: $?";
 		unlink ($filename);
 		unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
-		&newcleanssldatabase();
+		&cleanssldatabase();
 		goto VPNCONF_ERROR;
 	    } else {
 		unlink ($filename);
@@ -4284,7 +4312,7 @@ if ($cgiparams{'TYPE'} eq 'net') {
 		unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem");
 		unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem");
 		unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
-		&newcleanssldatabase();
+		&cleanssldatabase();
 		goto VPNCONF_ERROR;
 	    } else {
 		unlink ("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem");
@@ -4390,82 +4418,13 @@ if ($cgiparams{'TYPE'} eq 'net') {
 
 	&General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
 
-	if ($cgiparams{'CHECK1'} ){
-
-		my ($ccdip,$ccdsub)=split "/",$cgiparams{$name};
-		my ($a,$b,$c,$d) = split (/\./,$ccdip);
-			if ( -e "${General::swroot}/ovpn/ccd/$confighash{$key}[2]"){
-				unlink "${General::swroot}/ovpn/ccd/$cgiparams{'CERT_NAME'}";
-			}
-			open ( CCDRWCONF,'>',"${General::swroot}/ovpn/ccd/$confighash{$key}[2]") or die "Unable to create clientconfigfile $!";
-			print CCDRWCONF "# OpenVPN clientconfig from ccd extension by Copymaster#\n\n";
-			if($cgiparams{'CHECK1'} eq 'dynamic'){
-				print CCDRWCONF "#This client uses the dynamic pool\n";
-			}else{
-				print CCDRWCONF "#Ip address client and server\n";
-				print CCDRWCONF "ifconfig-push $ccdip ". &Network::bin2ip(&Network::ip2bin($ccdip) - 1) ."\n";
-			}
-			if ($confighash{$key}[34] eq 'on'){
-				print CCDRWCONF "\n#Redirect Gateway: \n#All IP traffic is redirected through the vpn \n";
-				print CCDRWCONF "push redirect-gateway\n";
-			}
-			&General::readhasharray("${General::swroot}/ovpn/ccdroute", \%ccdroutehash);
-			if ($cgiparams{'IR'} ne ''){
-				print CCDRWCONF "\n#Client routes these networks (behind Client)\n";
-				foreach my $key (keys %ccdroutehash){
-					if ($ccdroutehash{$key}[0] eq $cgiparams{'NAME'}){
-						foreach my $i ( 1 .. $#{$ccdroutehash{$key}}){
-							my ($a,$b)=split (/\//,$ccdroutehash{$key}[$i]);
-							print CCDRWCONF "iroute $a $b\n";
-						}
-					}
-				}
-			}
-			if ($cgiparams{'IFROUTE'} eq $Lang::tr{'ccd none'} ){$cgiparams{'IFROUTE'}='';}
-			if ($cgiparams{'IFROUTE'} ne ''){
-				print CCDRWCONF "\n#Client gets routes to these networks (behind IPFire)\n";
-				foreach my $key (keys %ccdroute2hash){
-					if ($ccdroute2hash{$key}[0] eq $cgiparams{'NAME'}){
-						foreach my $i ( 1 .. $#{$ccdroute2hash{$key}}){
-							if($ccdroute2hash{$key}[$i] eq $Lang::tr{'blue'}){
-								my %blue=();
-								&General::readhash("${General::swroot}/ethernet/settings", \%blue);
-								print CCDRWCONF "push \"route $blue{BLUE_ADDRESS} $blue{BLUE_NETMASK}\n";
-							}elsif($ccdroute2hash{$key}[$i] eq $Lang::tr{'orange'}){
-								my %orange=();
-								&General::readhash("${General::swroot}/ethernet/settings", \%orange);
-								print CCDRWCONF "push \"route $orange{ORANGE_ADDRESS}  $orange{ORANGE_NETMASK}\n";
-							}else{
-								my ($a,$b)=split (/\//,$ccdroute2hash{$key}[$i]);
-								print CCDRWCONF "push \"route $a $b\"\n";
-							}
-						}
-					}
-				}
-			}
-			if(($cgiparams{'CCD_DNS1'} eq '') && ($cgiparams{'CCD_DNS1'} ne '')){ $cgiparams{'CCD_DNS1'} = $cgiparams{'CCD_DNS2'};$cgiparams{'CCD_DNS2'}='';}
-			if($cgiparams{'CCD_DNS1'} ne ''){
-				print CCDRWCONF "\n#Client gets these nameservers\n";
-				print CCDRWCONF "push \"dhcp-option DNS $cgiparams{'CCD_DNS1'}\" \n";
-			}
-			if($cgiparams{'CCD_DNS2'} ne ''){
-				print CCDRWCONF "push \"dhcp-option DNS $cgiparams{'CCD_DNS2'}\" \n";
-			}
-			if($cgiparams{'CCD_WINS'} ne ''){
-				print CCDRWCONF "\n#Client gets this WINS server\n";
-				print CCDRWCONF "push \"dhcp-option WINS $cgiparams{'CCD_WINS'}\" \n";
-			}
-			close CCDRWCONF;
-	}
-
-###
-# m.a.d n2n begin
-###
+	# Rewrite the server configuration
+	&writeserverconf();
 
 	if ($cgiparams{'TYPE'} eq 'net') {
 
 		if (-e "/var/run/$confighash{$key}[1]n2n.pid") {
-			&General::system("/usr/local/bin/openvpnctrl", "-kn2n", "$confighash{$cgiparams{'KEY'}}[1]");
+			&General::system("/usr/local/bin/openvpnctrl", "n2n", "stop", "$confighash{$cgiparams{'KEY'}}[1]");
 
 			&General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
 			my $key = $cgiparams{'KEY'};
@@ -4479,30 +4438,16 @@ if ($cgiparams{'TYPE'} eq 'net') {
 			$confighash{$key}[0] = 'on';
 			&General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
 
-			&General::system("/usr/local/bin/openvpnctrl", "-sn2n", "$confighash{$cgiparams{'KEY'}}[1]");
+			&General::system("/usr/local/bin/openvpnctrl", "n2n", "start", "$confighash{$cgiparams{'KEY'}}[1]");
 		}
 	}
 
-###
-# m.a.d n2n end
-###
-
-	if ($cgiparams{'EDIT_ADVANCED'} eq 'on') {
-	    $cgiparams{'KEY'} = $key;
-	    $cgiparams{'ACTION'} = $Lang::tr{'advanced'};
-	}
 	goto VPNCONF_END;
     } else {
         $cgiparams{'ENABLED'} = 'on';
-###
-# m.a.d n2n begin
-###
         $cgiparams{'MSSFIX'} = 'on';
         $cgiparams{'FRAGMENT'} = '1300';
-	$cgiparams{'DAUTH'} = 'SHA512';
-###
-# m.a.d n2n end
-###
+        $cgiparams{'DAUTH'} = 'SHA512';
         $cgiparams{'SIDE'} = 'left';
 	if ( ! -f "${General::swroot}/ovpn/ca/cakey.pem" ) {
 	    $cgiparams{'AUTH'} = 'psk';
@@ -4511,7 +4456,7 @@ if ($cgiparams{'TYPE'} eq 'net') {
 	} else {
             $cgiparams{'AUTH'} = 'certgen';
 	}
-	$cgiparams{'LOCAL_SUBNET'}      ="$netsettings{'GREEN_NETADDRESS'}/$netsettings{'GREEN_NETMASK'}";
+	$cgiparams{'LOCAL_SUBNET'}      ="$Network::ethernet{'GREEN_NETADDRESS'}/$Network::ethernet{'GREEN_NETMASK'}";
 	$cgiparams{'CERT_ORGANIZATION'} = $vpnsettings{'ROOTCERT_ORGANIZATION'};
 	$cgiparams{'CERT_CITY'}         = $vpnsettings{'ROOTCERT_CITY'};
 	$cgiparams{'CERT_STATE'}        = $vpnsettings{'ROOTCERT_STATE'};
@@ -4523,17 +4468,8 @@ if ($cgiparams{'TYPE'} eq 'net') {
     $checked{'ENABLED'}{'off'} = '';
     $checked{'ENABLED'}{'on'} = '';
     $checked{'ENABLED'}{$cgiparams{'ENABLED'}} = 'CHECKED';
-    $checked{'ENABLED_BLUE'}{'off'} = '';
-    $checked{'ENABLED_BLUE'}{'on'} = '';
-    $checked{'ENABLED_BLUE'}{$cgiparams{'ENABLED_BLUE'}} = 'CHECKED';
-    $checked{'ENABLED_ORANGE'}{'off'} = '';
-    $checked{'ENABLED_ORANGE'}{'on'} = '';
-    $checked{'ENABLED_ORANGE'}{$cgiparams{'ENABLED_ORANGE'}} = 'CHECKED';
 
-
-    $checked{'EDIT_ADVANCED'}{'off'} = '';
-    $checked{'EDIT_ADVANCED'}{'on'} = '';
-    $checked{'EDIT_ADVANCED'}{$cgiparams{'EDIT_ADVANCED'}} = 'CHECKED';
+	$checked{'OTP_STATE'}{$cgiparams{'OTP_STATE'}} = 'CHECKED';
 
     $selected{'SIDE'}{'server'} = '';
     $selected{'SIDE'}{'client'} = '';
@@ -4576,11 +4512,6 @@ if ($cgiparams{'TYPE'} eq 'net') {
     $selected{'DCIPHER'}{'CAST5-CBC'} = '';
     $selected{'DCIPHER'}{'BF-CBC'} = '';
     $selected{'DCIPHER'}{'DES-CBC'} = '';
-    # If no cipher has been chossen yet, select
-    # the old default (AES-256-CBC) for compatiblity reasons.
-    if ($cgiparams{'DCIPHER'} eq '') {
-	$cgiparams{'DCIPHER'} = 'AES-256-CBC';
-    }
     $selected{'DCIPHER'}{$cgiparams{'DCIPHER'}} = 'SELECTED';
     $selected{'DAUTH'}{'whirlpool'} = '';
     $selected{'DAUTH'}{'SHA512'} = '';
@@ -4594,14 +4525,11 @@ if ($cgiparams{'TYPE'} eq 'net') {
 
     if (1) {
 	&Header::showhttpheaders();
-	&Header::openpage($Lang::tr{'ovpn'}, 1, '');
-	&Header::openbigbox('100%', 'LEFT', '', $errormessage);
-	if ($errormessage) {
-	    &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
-	    print "<class name='base'>$errormessage";
-	    print "&nbsp;</class>";
-	    &Header::closebox();
-	}
+	&Header::openpage($Lang::tr{'ovpn'}, 1, '');
+	&Header::openbigbox('100%', 'LEFT', '', $errormessage);
+
+	# Show any errors
+	&Header::errorbox($errormessage);
 
 	if ($warnmessage) {
 	    &Header::openbox('100%', 'LEFT', "$Lang::tr{'warning messages'}:");
@@ -4619,34 +4547,22 @@ if ($cgiparams{'TYPE'} eq 'net') {
 	}
 
 	&Header::openbox('100%', 'LEFT', "$Lang::tr{'connection'}:");
-	print "<table width='100%'  border='0'>\n";
 
-	print "<tr><td width='14%' class='boldbase'>$Lang::tr{'name'}:&nbsp;<img src='/blob.gif' alt='*' /></td>";
+	my $readonly = ($cgiparams{'KEY'}) ? "readonly" : "";
 
-	if ($cgiparams{'TYPE'} eq 'host') {
-	    if ($cgiparams{'KEY'}) {
-		print "<td width='35%' class='base'><input type='hidden' name='NAME' value='$cgiparams{'NAME'}' />$cgiparams{'NAME'}</td>";
-	    } else {
-		print "<td width='35%'><input type='text' name='NAME' value='$cgiparams{'NAME'}' maxlength='20' size='30' /></td>";
-	    }
-#	    print "<tr><td>$Lang::tr{'interface'}</td>";
-#	    print "<td><select name='INTERFACE'>";
-#	    print "<option value='RED' $selected{'INTERFACE'}{'RED'}>RED</option>";
-#		if ($netsettings{'BLUE_DEV'} ne '') {
-#			print "<option value='BLUE' $selected{'INTERFACE'}{'BLUE'}>BLUE</option>";
-#		}
-#		print "<option value='GREEN' $selected{'INTERFACE'}{'GREEN'}>GREEN</option>";
-#		print "<option value='ORANGE' $selected{'INTERFACE'}{'ORANGE'}>ORANGE</option>";
-#		print "</select></td></tr>";
-#		print <<END;
-	} else {
-	    print "<input type='hidden' name='INTERFACE' value='red' />";
-	    if ($cgiparams{'KEY'}) {
-		print "<td width='25%' class='base' nowrap='nowrap'><input type='hidden' name='NAME' value='$cgiparams{'NAME'}' />$cgiparams{'NAME'}</td>";
-	    } else {
-		print "<td width='25%'><input type='text' name='NAME' value='$cgiparams{'NAME'}' maxlength='20' /></td>";
-	    }
+	print <<END;
+		<table class="form">
+			<tr>
+				<td>
+					$Lang::tr{'name'}
+				</td>
+				<td>
+					<input type="text" name="NAME" value="$cgiparams{'NAME'}" $readonly/>
+				</td>
+			</tr>
+END
 
+	if ($cgiparams{'TYPE'} eq 'net') {
 		# If GCM ciphers are in usage, HMAC menu is disabled
 		my $hmacdisabled;
 		if (($confighash{$cgiparams{'KEY'}}[40] eq 'AES-256-GCM') ||
@@ -4720,7 +4636,7 @@ if ($cgiparams{'TYPE'} eq 'net') {
 
 <tr><td colspan=4><hr /></td></tr><tr>
 	<tr>
-		<td class='base'><b>$Lang::tr{'ovpn crypt options'}:</b></td>
+		<td class='base'><b>$Lang::tr{'ovpn crypto settings'}:</b></td>
 	</tr>
 
 	<tr><td class='boldbase'>$Lang::tr{'cipher'}</td>
@@ -4757,7 +4673,6 @@ if ($cgiparams{'TYPE'} eq 'net') {
 
 END
 ;
-	}
 
 #### JAVA SCRIPT ####
 # Validate N2N cipher. If GCM will be used, HMAC menu will be disabled onchange
@@ -4773,17 +4688,50 @@ print<<END;
 		}
 	</script>
 END
+	}
 
-#jumper
-	print "<tr><td class='boldbase'>$Lang::tr{'remark title'}</td>";
-	print "<td colspan='3'><input type='text' name='REMARK' value='$cgiparams{'REMARK'}' size='55' maxlength='50' /></td></tr></table>";
+	# Remark
+	print <<END;
+		<tr>
+			<td>
+				$Lang::tr{'remark title'}
+			</td>
+			<td>
+				<input type="text" name="REMARK" value="$cgiparams{'REMARK'}" />
+			</td>
+		</tr>
+END
 
+	# Enabled?
 	if ($cgiparams{'TYPE'} eq 'host') {
-      print "<tr><td>$Lang::tr{'enabled'} <input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} /></td>";
+		print <<END;
+			<tr>
+				<td>
+					$Lang::tr{'enabled'}
+				</td>
+				<td>
+					<input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} />
+				</td>
+			</tr>
+END
     }
 
-		print"</tr></table><br><br>";
-#A.Marx CCD new client
+	# OTP?
+	if ($cgiparams{'TYPE'} eq 'host') {
+		print <<END;
+			<tr>
+				<td>
+					$Lang::tr{'enable otp'}
+				</td>
+				<td>
+					<input type='checkbox' name='OTP_STATE' $checked{'OTP_STATE'}{'on'} />
+				</td>
+			</tr>
+END
+	}
+
+	print "</table>";
+
 if ($cgiparams{'TYPE'} eq 'host') {
 	    print "<table border='0' width='100%' cellspacing='1' cellpadding='0'><tr><td colspan='3'><hr><br><b>$Lang::tr{'ccd choose net'}</td></tr><tr><td height='20' colspan='3'></td></tr>";
 	    my %vpnnet=();
@@ -4801,22 +4749,21 @@ if ($cgiparams{'TYPE'} eq 'host') {
 	    print"</td></tr></table><br><br>";
 		my $name=$cgiparams{'CHECK1'};
 		$checked{'RG'}{$cgiparams{'RG'}} = 'CHECKED';
-		$checked{'OTP_STATE'}{$cgiparams{'OTP_STATE'}} = 'CHECKED';
 
 	if (! -z "${General::swroot}/ovpn/ccd.conf"){
 		print"<table border='0' width='100%' cellspacing='1' cellpadding='0'><tr><td width='1%'></td><td width='30%' class='boldbase' align='center'><b>$Lang::tr{'ccd name'}</td><td width='15%' class='boldbase' align='center'><b>$Lang::tr{'network'}</td><td class='boldbase' align='center' width='18%'><b>$Lang::tr{'ccd clientip'}</td></tr>";
 		foreach my $key (sort { uc($ccdconfhash{$a}[0]) cmp uc($ccdconfhash{$b}[0]) } keys %ccdconfhash) {
 			$count++;
 			@ccdconf=($ccdconfhash{$key}[0],$ccdconfhash{$key}[1]);
-			if ($count % 2){print"<tr bgcolor='$color{'color22'}'>";}else{print"<tr bgcolor='$color{'color20'}'>";}
+			if ($count % 2){print"<tr bgcolor='$Header::color{'color22'}'>";}else{print"<tr bgcolor='$Header::color{'color20'}'>";}
 			print"<td align='center' width='1%'><input type='radio' name='CHECK1' value='$ccdconf[0]' $checked{'check1'}{$ccdconf[0]}/></td><td>$ccdconf[0]</td><td width='40%' align='center'>$ccdconf[1]</td><td align='left' width='10%'>";
-			&fillselectbox($ccdconf[1],$ccdconf[0],$cgiparams{$name});
+			&fillselectbox($ccdconf[0], $ccdconf[1], &convert_top30_ccd_allocation($cgiparams{$name}));
 			print"</td></tr>";
 		}
 		print "</table><br><br><hr><br><br>";
 	}
 }
-# ccd end
+
 	&Header::closebox();
 	if ($cgiparams{'KEY'} && $cgiparams{'AUTH'} eq 'psk') {
 
@@ -4853,10 +4800,6 @@ if ($cgiparams{'TYPE'} eq 'host') {
 END
 ;
 
-###
-# m.a.d net2net
-###
-
 } else {
 
 	print <<END;
@@ -4877,10 +4820,6 @@ END
 
 }
 
-###
-# m.a.d net2net
-###
-
 	    foreach my $country (sort keys %{Countries::countries}) {
 		print "<option value='$Countries::countries{$country}'";
 		if ( $Countries::countries{$country} eq $cgiparams{'CERT_COUNTRY'} ) {
@@ -4888,9 +4827,6 @@ END
 		}
 		print ">$country</option>";
 	    }
-###
-# m.a.d net2net
-###
 
 if ($cgiparams{'TYPE'} eq 'host') {
 	print <<END;
@@ -4921,15 +4857,10 @@ END
 END
 }
 
-###
-# m.a.d net2net
-###
-	    ;
 	    &Header::closebox();
 
 	}
 
-#A.Marx CCD new client
 if ($cgiparams{'TYPE'} eq 'host') {
 	    print"<br><br>";
 	    &Header::openbox('100%', 'LEFT', "$Lang::tr{'ccd client options'}:");
@@ -4937,7 +4868,6 @@ if ($cgiparams{'TYPE'} eq 'host') {
 
 	print <<END;
 	<table border='0' width='100%'>
-	<tr><td width='20%'>$Lang::tr{'enable otp'}:</td><td colspan='3'><input type='checkbox' name='OTP_STATE' $checked{'OTP_STATE'}{'on'} /></td></tr>
 	<tr><td width='20%'>Redirect Gateway:</td><td colspan='3'><input type='checkbox' name='RG' $checked{'RG'}{'on'} /></td></tr>
 	<tr><td colspan='4'><b><br>$Lang::tr{'ccd routes'}</b></td></tr>
 	<tr><td colspan='4'>&nbsp</td></tr>
@@ -4961,7 +4891,7 @@ END
 	}
 
 	print <<END;
-</textarea></td><td valign='top' colspan='2'>$Lang::tr{'ccd iroutehint'}</td></tr>
+</textarea></td><td valign='top' colspan='2'></td></tr>
 	<tr><td colspan='4'><br></td></tr>
 	<tr><td valign='top' rowspan='3'>$Lang::tr{'ccd iroute2'}</td><td align='left' valign='top' rowspan='3'><select name='IFROUTE' style="width: 205px"; size='6' multiple>
 END
@@ -5048,24 +4978,24 @@ END
 		if($ccdroute2hash{$key}[0] eq $cgiparams{'NAME'}){
 			$other=1;
 			foreach my $i (1 .. $#{$ccdroute2hash{$key}}) {
-				if ($ccdroute2hash{$key}[$i] eq $netsettings{'GREEN_NETADDRESS'}."/".&General::iporsubtodec($netsettings{'GREEN_NETMASK'})){
+				if ($ccdroute2hash{$key}[$i] eq $Network::ethernet{'GREEN_NETADDRESS'}."/".&General::iporsubtodec($Network::ethernet{'GREEN_NETMASK'})){
 					$selgreen=1;
 				}
-				if (&haveBlueNet()){
-					if( $ccdroute2hash{$key}[$i] eq $netsettings{'BLUE_NETADDRESS'}."/".&General::iporsubtodec($netsettings{'BLUE_NETMASK'})) {
+				if (&Header::blue_used()){
+					if( $ccdroute2hash{$key}[$i] eq $Network::ethernet{'BLUE_NETADDRESS'}."/".&General::iporsubtodec($Network::ethernet{'BLUE_NETMASK'})) {
 						$selblue=1;
 					}
 				}
-				if (&haveOrangeNet()){
-					if( $ccdroute2hash{$key}[$i] eq $netsettings{'ORANGE_NETADDRESS'}."/".&General::iporsubtodec($netsettings{'ORANGE_NETMASK'}) ) {
+				if (&Header::orange_used()){
+					if( $ccdroute2hash{$key}[$i] eq $Network::ethernet{'ORANGE_NETADDRESS'}."/".&General::iporsubtodec($Network::ethernet{'ORANGE_NETMASK'}) ) {
 						$selorange=1;
 					}
 				}
 			}
 		}
 	}
-	if (&haveBlueNet() && $selblue == '1'){ print"<option selected>$Lang::tr{'blue'}</option>";$selblue=0;}elsif(&haveBlueNet() && $selblue == '0'){print"<option>$Lang::tr{'blue'}</option>";}
-	if (&haveOrangeNet() && $selorange == '1'){ print"<option selected>$Lang::tr{'orange'}</option>";$selorange=0;}elsif(&haveOrangeNet() && $selorange == '0'){print"<option>$Lang::tr{'orange'}</option>";}
+	if (&Header::blue_used() && $selblue == '1'){ print"<option selected>$Lang::tr{'blue'}</option>";$selblue=0;}elsif(&Header::blue_used() && $selblue == '0'){print"<option>$Lang::tr{'blue'}</option>";}
+	if (&Header::orange_used() && $selorange == '1'){ print"<option selected>$Lang::tr{'orange'}</option>";$selorange=0;}elsif(&Header::orange_used() && $selorange == '0'){print"<option>$Lang::tr{'orange'}</option>";}
 	if ($selgreen == '1' || $other == '0'){ print"<option selected>$Lang::tr{'green'}</option>";$set=0;}else{print"<option>$Lang::tr{'green'}</option>";};
 
 	print<<END;
@@ -5078,9 +5008,6 @@ END
      &Header::closebox();
 }
 	print "<div align='center'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' />";
-	if ($cgiparams{'KEY'}) {
-#	    print "<input type='submit' name='ACTION' value='$Lang::tr{'advanced'}' />";
-	}
 	print "<input type='submit' name='ACTION' value='$Lang::tr{'cancel'}' /></div></form>";
 	&Header::closebigbox();
 	&Header::closepage();
@@ -5089,116 +5016,24 @@ END
     VPNCONF_END:
 }
 
-#    SETTINGS_ERROR:
-###
-### Default status page
-###
-    %cgiparams = ();
     %cahash = ();
     %confighash = ();
-    &General::readhash("${General::swroot}/ovpn/settings", \%cgiparams);
     &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
 
-    open(FILE, "/var/run/ovpnserver.log");
-    my @status = <FILE>;
-    close(FILE);
+    my @status = ();
 
-    if ($cgiparams{'VPN_IP'} eq '' && -e "${General::swroot}/red/active") {
-		if (open(IPADDR, "${General::swroot}/red/local-ipaddress")) {
-		    my $ipaddr = <IPADDR>;
-		    close IPADDR;
-		    chomp ($ipaddr);
-		    $cgiparams{'VPN_IP'} = (gethostbyaddr(pack("C4", split(/\./, $ipaddr)), 2))[0];
-		    if ($cgiparams{'VPN_IP'} eq '') {
-				$cgiparams{'VPN_IP'} = $ipaddr;
-		    }
-		}
+    # Only load status when the RW server is enabled
+    if ($vpnsettings{'ENABLED'} eq 'on') {
+	open(FILE, "/usr/local/bin/openvpnctrl rw log |");
+	@status = <FILE>;
+	close(FILE);
     }
 
-#default setzen
-    if ($cgiparams{'DCIPHER'} eq '') {
-		$cgiparams{'DCIPHER'} =  'AES-256-CBC';
-    }
-    if ($cgiparams{'DDEST_PORT'} eq '') {
-		$cgiparams{'DDEST_PORT'} =  '1194';
-    }
-    if ($cgiparams{'DMTU'} eq '') {
-		$cgiparams{'DMTU'} =  '1400';
-    }
-    if ($cgiparams{'MSSFIX'} eq '') {
-		$cgiparams{'MSSFIX'} = 'off';
-    }
-	if ($cgiparams{'DAUTH'} eq '') {
-		if (-z "${General::swroot}/ovpn/ovpnconfig") {
-			$cgiparams{'DAUTH'} = 'SHA512';
-		}
-		foreach my $key (keys %confighash) {
-			if ($confighash{$key}[3] ne 'host') {
-				$cgiparams{'DAUTH'} = 'SHA512';
-			} else {
-				$cgiparams{'DAUTH'} = 'SHA1';
-			}
-		}
-	}
-	if ($cgiparams{'TLSAUTH'} eq '') {
-		$cgiparams{'TLSAUTH'} = 'off';
-	}
-    if ($cgiparams{'DOVPN_SUBNET'} eq '') {
-		$cgiparams{'DOVPN_SUBNET'} = '10.' . int(rand(256)) . '.' . int(rand(256)) . '.0/255.255.255.0';
-    }
     $checked{'ENABLED'}{'off'} = '';
     $checked{'ENABLED'}{'on'} = '';
-    $checked{'ENABLED'}{$cgiparams{'ENABLED'}} = 'CHECKED';
-    $checked{'ENABLED_BLUE'}{'off'} = '';
-    $checked{'ENABLED_BLUE'}{'on'} = '';
-    $checked{'ENABLED_BLUE'}{$cgiparams{'ENABLED_BLUE'}} = 'CHECKED';
-    $checked{'ENABLED_ORANGE'}{'off'} = '';
-    $checked{'ENABLED_ORANGE'}{'on'} = '';
-    $checked{'ENABLED_ORANGE'}{$cgiparams{'ENABLED_ORANGE'}} = 'CHECKED';
-
-    $selected{'DPROTOCOL'}{'udp'} = '';
-    $selected{'DPROTOCOL'}{'tcp'} = '';
-    $selected{'DPROTOCOL'}{$cgiparams{'DPROTOCOL'}} = 'SELECTED';
-
-    $selected{'DCIPHER'}{'AES-256-GCM'} = '';
-    $selected{'DCIPHER'}{'AES-192-GCM'} = '';
-    $selected{'DCIPHER'}{'AES-128-GCM'} = '';
-    $selected{'DCIPHER'}{'CAMELLIA-256-CBC'} = '';
-    $selected{'DCIPHER'}{'CAMELLIA-192-CBC'} = '';
-    $selected{'DCIPHER'}{'CAMELLIA-128-CBC'} = '';
-    $selected{'DCIPHER'}{'AES-256-CBC'} = '';
-    $selected{'DCIPHER'}{'AES-192-CBC'} = '';
-    $selected{'DCIPHER'}{'AES-128-CBC'} = '';
-    $selected{'DCIPHER'}{'DES-EDE3-CBC'} = '';
-    $selected{'DCIPHER'}{'DESX-CBC'} = '';
-    $selected{'DCIPHER'}{'SEED-CBC'} = '';
-    $selected{'DCIPHER'}{'DES-EDE-CBC'} = '';
-    $selected{'DCIPHER'}{'CAST5-CBC'} = '';
-    $selected{'DCIPHER'}{'BF-CBC'} = '';
-    $selected{'DCIPHER'}{'DES-CBC'} = '';
-    $selected{'DCIPHER'}{$cgiparams{'DCIPHER'}} = 'SELECTED';
-
-    $selected{'DAUTH'}{'whirlpool'} = '';
-    $selected{'DAUTH'}{'SHA512'} = '';
-    $selected{'DAUTH'}{'SHA384'} = '';
-    $selected{'DAUTH'}{'SHA256'} = '';
-    $selected{'DAUTH'}{'SHA1'} = '';
-    $selected{'DAUTH'}{$cgiparams{'DAUTH'}} = 'SELECTED';
-
-    $checked{'TLSAUTH'}{'off'} = '';
-    $checked{'TLSAUTH'}{'on'} = '';
-    $checked{'TLSAUTH'}{$cgiparams{'TLSAUTH'}} = 'CHECKED';
+    $checked{'ENABLED'}{$vpnsettings{'ENABLED'}} = 'CHECKED';
 
-    $checked{'DCOMPLZO'}{'off'} = '';
-    $checked{'DCOMPLZO'}{'on'} = '';
-    $checked{'DCOMPLZO'}{$cgiparams{'DCOMPLZO'}} = 'CHECKED';
-
-# m.a.d
-    $checked{'MSSFIX'}{'off'} = '';
-    $checked{'MSSFIX'}{'on'} = '';
-    $checked{'MSSFIX'}{$cgiparams{'MSSFIX'}} = 'CHECKED';
-#new settings
     &Header::showhttpheaders();
     &Header::openpage($Lang::tr{'status ovpn'}, 1, '');
     &Header::openbigbox('100%', 'LEFT', '', $errormessage);
@@ -5206,20 +5041,6 @@ END
 	# Show any errors and warnings
 	&Header::errorbox($errormessage);
 
-	if ($cryptoerror) {
-		&Header::openbox('100%', 'LEFT', $Lang::tr{'crypto error'});
-		print "<class name='base'>$cryptoerror";
-		print "&nbsp;</class>";
-		&Header::closebox();
-	}
-
-	if ($cryptowarning) {
-		&Header::openbox('100%', 'LEFT', $Lang::tr{'crypto warning'});
-		print "<class name='base'>$cryptowarning";
-		print "&nbsp;</class>";
-		&Header::closebox();
-	}
-
 	if ($warnmessage) {
 		&Header::openbox('100%', 'LEFT', $Lang::tr{'warning messages'});
 		print "$warnmessage<br>";
@@ -5230,442 +5051,318 @@ END
 		exit 0;
 	}
 
-    my $sactive = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourred}' width='50%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'stopped'}</font></b></td></tr></table>";
-    my $srunning = "no";
-    my $activeonrun = "";
-    if ( -e "/var/run/openvpn.pid"){
-	$sactive = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourgreen}' width='50%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'running'}</font></b></td></tr></table>";
-	$srunning ="yes";
-	$activeonrun = "";
-    } else {
-	$activeonrun = "disabled='disabled'";
-    }
-    &Header::openbox('100%', 'LEFT', $Lang::tr{'global settings'});
+    &Header::openbox('100%', 'LEFT', $Lang::tr{'ovpn roadwarrior settings'});
 
 	# Show the service status
 	&Header::ServiceStatus({
 		$Lang::tr{'ovpn roadwarrior server'} => {
 			"process" => "openvpn",
-			"pidfile" => "/var/run/openvpn.pid",
+			"pidfile" => "/var/run/openvpn-rw.pid",
 		}
 	});
 
 	print <<END;
-    <table width='100%' border='0'>
-    <form method='post'>
-    <td width='25%'>&nbsp;</td>
-    <td width='25%'>&nbsp;</td>
-    <td width='25%'>&nbsp;</td></tr>
-    <tr><td class='boldbase'>$Lang::tr{'ovpn server status'}</td>
-    <td align='left'>$sactive</td>
-    <tr><td class='boldbase'>$Lang::tr{'ovpn on red'}</td>
-    <td><input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} /></td>
+	    <form method='POST'>
+		    <table class="form">
+				<tr>
+					<td class='boldbase'>
+						$Lang::tr{'enabled'}
+					</td>
+					<td>
+						<input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} />
+					</td>
+				</tr>
+
+				<tr>
+					<td colspan='2'></td>
+				</tr>
+
+				<tr>
+					<td>
+						$Lang::tr{'ovpn fqdn'}
+					</td>
+					<td>
+						<input type='text' name='VPN_IP' value='$vpnsettings{'VPN_IP'}' />
+					</td>
+				</tr>
+
+				<tr>
+					<td>
+						$Lang::tr{'ovpn dynamic client subnet'}
+					</td>
+					<td>
+						<input type='TEXT' name='DOVPN_SUBNET' value='$vpnsettings{'DOVPN_SUBNET'}' />
+					</td>
+				</tr>
+
+				<tr class="action">
+					<td colspan="2">
+						<input type='submit' name='ACTION' value='$Lang::tr{'save'}' />
+						<input type='submit' name='ACTION' value='$Lang::tr{'ccd net'}' />
+						<input type='submit' name='ACTION' value='$Lang::tr{'advanced server'}' />
+					</td>
+				</tr>
+			</table>
+		</form>
 END
-;
-    if (&haveBlueNet()) {
-	print "<tr><td class='boldbase'>$Lang::tr{'ovpn on blue'}</td>";
-	print "<td><input type='checkbox' name='ENABLED_BLUE' $checked{'ENABLED_BLUE'}{'on'} /></td>";
-    }
-    if (&haveOrangeNet()) {
-	print "<tr><td class='boldbase'>$Lang::tr{'ovpn on orange'}</td>";
-	print "<td><input type='checkbox' name='ENABLED_ORANGE' $checked{'ENABLED_ORANGE'}{'on'} /></td>";
-    }
 
+    &Header::closebox();
+
+    &Header::openbox('100%', 'LEFT', $Lang::tr{'connection status and controlc' });
 	print <<END;
+		<table class='tbl'>
+			<tr>
+				<th width='15%'>
+					$Lang::tr{'name'}
+				</th>
+				<th width='10%'>
+					$Lang::tr{'type'}
+				</th>
+				<th>
+					$Lang::tr{'remark'}
+				</th>
+				<th width='10%'>
+					$Lang::tr{'status'}
+				</th>
+				<th width='5%' colspan='8'>
+					$Lang::tr{'action'}
+				</th>
+			</tr>
+END
 
-	<tr><td colspan='4'><br></td></tr>
-	<tr>
-		<td class='base'><b>$Lang::tr{'net config'}:</b></td>
-	</tr>
-    <tr><td colspan='1'><br></td></tr>
-
-    <tr><td class='base' nowrap='nowrap' colspan='2'>$Lang::tr{'local vpn hostname/ip'}:<br /><input type='text' name='VPN_IP' value='$cgiparams{'VPN_IP'}' size='30' /></td>
-	<td class='boldbase' nowrap='nowrap' colspan='2'>$Lang::tr{'ovpn subnet'}<br /><input type='TEXT' name='DOVPN_SUBNET' value='$cgiparams{'DOVPN_SUBNET'}' size='30' /></td></tr>
-    <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'protocol'}</td>
-        <td><select name='DPROTOCOL'><option value='udp' $selected{'DPROTOCOL'}{'udp'}>UDP</option>
-               			    <option value='tcp' $selected{'DPROTOCOL'}{'tcp'}>TCP</option></select></td>
-        <td class='boldbase'>$Lang::tr{'destination port'}:</td>
-        <td><input type='TEXT' name='DDEST_PORT' value='$cgiparams{'DDEST_PORT'}' size='5' /></td></tr>
-    <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'MTU'}&nbsp;</td>
-        <td> <input type='TEXT' name='DMTU' VALUE='$cgiparams{'DMTU'}' size='5' /></td>
-    </tr>
+	my $gif;
 
-	<tr><td colspan='4'><br></td></tr>
-	<tr>
-		<td class='base'><b>$Lang::tr{'ovpn crypt options'}:</b></td>
-	</tr>
-	<tr><td colspan='1'><br></td></tr>
+	foreach my $key (sort { ncmp ($confighash{$a}[1],$confighash{$b}[1]) } keys %confighash) {
+		my $status = $confighash{$key}[0];
+		my $name   = $confighash{$key}[1];
+		my $type   = $confighash{$key}[3];
 
-	<tr>
-		<td class='base'>$Lang::tr{'ovpn ha'}</td>
-		<td><select name='DAUTH'>
-				<option value='whirlpool'		$selected{'DAUTH'}{'whirlpool'}>Whirlpool (512 $Lang::tr{'bit'})</option>
-				<option value='SHA512'			$selected{'DAUTH'}{'SHA512'}>SHA2 (512 $Lang::tr{'bit'})</option>
-				<option value='SHA384'			$selected{'DAUTH'}{'SHA384'}>SHA2 (384 $Lang::tr{'bit'})</option>
-				<option value='SHA256'			$selected{'DAUTH'}{'SHA256'}>SHA2 (256 $Lang::tr{'bit'})</option>
-				<option value='SHA1'			$selected{'DAUTH'}{'SHA1'}>SHA1 (160 $Lang::tr{'bit'}, $Lang::tr{'vpn weak'})</option>
-			</select>
-		</td>
+		# Create some simple booleans to check the status
+		my $hasExpired = 0;
+		my $expiresSoon = 0;
 
-		<td class='boldbase' nowrap='nowrap'>$Lang::tr{'cipher'}</td>
-		<td><select name='DCIPHER'>
-				<option value='AES-256-GCM' $selected{'DCIPHER'}{'AES-256-GCM'}>AES-GCM (256 $Lang::tr{'bit'})</option>
-				<option value='AES-192-GCM' $selected{'DCIPHER'}{'AES-192-GCM'}>AES-GCM (192 $Lang::tr{'bit'})</option>
-				<option value='AES-128-GCM' $selected{'DCIPHER'}{'AES-128-GCM'}>AES-GCM (128 $Lang::tr{'bit'})</option>
-				<option value='CAMELLIA-256-CBC' $selected{'DCIPHER'}{'CAMELLIA-256-CBC'}>CAMELLIA-CBC (256 $Lang::tr{'bit'})</option>
-				<option value='CAMELLIA-192-CBC' $selected{'DCIPHER'}{'CAMELLIA-192-CBC'}>CAMELLIA-CBC (192 $Lang::tr{'bit'})</option>
-				<option value='CAMELLIA-128-CBC' $selected{'DCIPHER'}{'CAMELLIA-128-CBC'}>CAMELLIA-CBC (128 $Lang::tr{'bit'})</option>
-				<option value='AES-256-CBC' $selected{'DCIPHER'}{'AES-256-CBC'}>AES-CBC (256 $Lang::tr{'bit'})</option>
-				<option value='AES-192-CBC' $selected{'DCIPHER'}{'AES-192-CBC'}>AES-CBC (192 $Lang::tr{'bit'})</option>
-				<option value='AES-128-CBC' $selected{'DCIPHER'}{'AES-128-CBC'}>AES-CBC (128 $Lang::tr{'bit'})</option>
-				<option value='SEED-CBC' $selected{'DCIPHER'}{'SEED-CBC'}>SEED-CBC (128 $Lang::tr{'bit'})</option>
-				<option value='DES-EDE3-CBC' $selected{'DCIPHER'}{'DES-EDE3-CBC'}>DES-EDE3-CBC (192 $Lang::tr{'bit'}, $Lang::tr{'vpn weak'})</option>
-				<option value='DESX-CBC' $selected{'DCIPHER'}{'DESX-CBC'}>DESX-CBC (192 $Lang::tr{'bit'}, $Lang::tr{'vpn weak'})</option>
-				<option value='DES-EDE-CBC' $selected{'DCIPHER'}{'DES-EDE-CBC'}>DES-EDE-CBC (128 $Lang::tr{'bit'}, $Lang::tr{'vpn weak'})</option>
-				<option value='BF-CBC' $selected{'DCIPHER'}{'BF-CBC'}>BF-CBC (128 $Lang::tr{'bit'}, $Lang::tr{'vpn weak'})</option>
-				<option value='CAST5-CBC' $selected{'DCIPHER'}{'CAST5-CBC'}>CAST5-CBC (128 $Lang::tr{'bit'}, $Lang::tr{'vpn weak'})</option>
-			</select>
-		</td>
-	</tr>
+		# Fetch information about the certificate for non-N2N connections only
+		if ($confighash{$key}[3] ne 'net') {
+			my @cavalid = &General::system_output("/usr/bin/openssl", "x509", "-text",
+				"-in", "${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem");
 
-    <tr><td colspan='4'><br></td></tr>
-	<tr>
-		<td class='base'>$Lang::tr{'ovpn tls auth'}</td>
-		<td><input type='checkbox' name='TLSAUTH' $checked{'TLSAUTH'}{'on'} /></td>
-	</tr>
+			my $expiryDate = 0;
 
-    <tr><td colspan='4'><br><br></td></tr>
-END
-;
+			# Parse the certificate information
+			foreach my $line (@cavalid) {
+				if ($line =~ /Not After : (.*)[\n]/) {
+					$expiryDate = &Date::Parse::str2time($1);
+					last;
+				}
+			}
 
-    if ( $srunning eq "yes" ) {
-	print "<tr><td align='right' colspan='4'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' disabled='disabled' />";
-	print "<input type='submit' name='ACTION' value='$Lang::tr{'ccd net'}' />";
-	print "<input type='submit' name='ACTION' value='$Lang::tr{'advanced server'}' />";
-	print "<input type='submit' name='ACTION' value='$Lang::tr{'stop ovpn server'}' /></td></tr>";
-    } else{
-	print "<tr><td align='right' colspan='4'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' />";
-	print "<input type='submit' name='ACTION' value='$Lang::tr{'ccd net'}' />";
-	print "<input type='submit' name='ACTION' value='$Lang::tr{'advanced server'}' />";
-	if (( -e "${General::swroot}/ovpn/ca/cacert.pem" &&
-	     -e "$dhparameter" &&
-	     -e "${General::swroot}/ovpn/certs/servercert.pem" &&
-	     -e "${General::swroot}/ovpn/certs/serverkey.pem") &&
-	    (( $cgiparams{'ENABLED'} eq 'on') ||
-	    ( $cgiparams{'ENABLED_BLUE'} eq 'on') ||
-	    ( $cgiparams{'ENABLED_ORANGE'} eq 'on'))){
-	    print "<input type='submit' name='ACTION' value='$Lang::tr{'start ovpn server'}' /></td></tr>";
-	} else {
-	    print "<input type='submit' name='ACTION' value='$Lang::tr{'start ovpn server'}' disabled='disabled' /></td></tr>";
-	}
-    }
-    print "</form></table>";
-    &Header::closebox();
+			# Calculate the remaining time
+			my $remainingTime = $expiryDate - time();
 
-    if ( -f "${General::swroot}/ovpn/ca/cacert.pem" ) {
-###
-# m.a.d net2net
-#<td width='25%' class='boldbase' align='center'><b>$Lang::tr{'remark'}</b><br /><img src='/images/null.gif' width='125' height='1' border='0' alt='L2089' /></td>
-###
+			# Determine whether the certificate has already expired, or will so soon
+			$hasExpired = ($remainingTime <= 0);
+			$expiresSoon = ($remainingTime <= 30 * 24 * 3600);
+		}
 
-    &Header::openbox('100%', 'LEFT', $Lang::tr{'connection status and controlc' });
-	;
-	my $id = 0;
-	my $gif;
-	my $col1="";
-	my $lastnet;
-	foreach my $key (sort { ncmp ($confighash{$a}[32],$confighash{$b}[32]) } sort { ncmp ($confighash{$a}[1],$confighash{$b}[1]) } keys %confighash) {
-		if ($confighash{$key}[32] eq "" && $confighash{$key}[3] eq 'net' ){$confighash{$key}[32]=$Lang::tr{'fwhost OpenVPN N-2-N'};}
-		if ($confighash{$key}[32] eq "dynamic"){$confighash{$key}[32]=$Lang::tr{'ccd dynrange'};}
-		if($id == 0){
-			print"<b>$confighash{$key}[32]</b>";
-			print <<END;
-	<table width='100%' cellspacing='1' cellpadding='0' class='tbl'>
-<tr>
-	<th width='10%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></th>
-	<th width='15%' class='boldbase' align='center'><b>$Lang::tr{'type'}</b></th>
-	<th width='20%' class='boldbase' align='center'><b>$Lang::tr{'remark'}</b></th>
-	<th width='10%' class='boldbase' align='center'><b>$Lang::tr{'status'}</b></th>
-	<th width='5%' class='boldbase' colspan='8' align='center'><b>$Lang::tr{'action'}</b></th>
-</tr>
-END
+		my @classes = ();
+
+		# Highlight the row if the certificate has expired/will expire soon
+		if ($hasExpired || $expiresSoon) {
+			push(@classes, "is-warning");
 		}
-		if ($id > 0 && $lastnet ne $confighash{$key}[32]){
-			print "</table><br>";
-			print"<b>$confighash{$key}[32]</b>";
-			print <<END;
-	<table width='100%' cellspacing='1' cellpadding='0' class='tbl'>
-<tr>
-	<th width='10%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></th>
-	<th width='15%' class='boldbase' align='center'><b>$Lang::tr{'type'}</b></th>
-	<th width='20%' class='boldbase' align='center'><b>$Lang::tr{'remark'}</b></th>
-	<th width='10%' class='boldbase' align='center'><b>$Lang::tr{'status'}</b></th>
-	<th width='5%' class='boldbase' colspan='8' align='center'><b>$Lang::tr{'action'}</b></th>
-</tr>
-END
+
+		# Start a new row
+		print "<tr class='@classes'>";
+
+		# Show the name of the connection
+		print "	<th scope='row'>$name";
+		if ($hasExpired) {
+			print " ($Lang::tr{'openvpn cert has expired'})";
+		} elsif ($expiresSoon) {
+			print " ($Lang::tr{'openvpn cert expires soon'})";
 		}
-	if ($confighash{$key}[0] eq 'on') { $gif = 'on.gif'; } else { $gif = 'off.gif'; }
+		print "</th>";
 
-	# Create some simple booleans to check the status
-	my $hasExpired;
-	my $expiresSoon;
+		# Show type
+		print "<td class='text-center'>$Lang::tr{$type}</td>";
 
-	# Fetch information about the certificate for non-N2N connections only
-	if ($confighash{$key}[3] ne 'net') {
-		my @cavalid = &General::system_output("/usr/bin/openssl", "x509", "-text",
-			"-in", "${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem");
+		# Show remarks
+		print "<td>$confighash{$key}[25]</td>";
 
-		my $expiryDate = 0;
+		my $connstatus = "DISCONNECTED";
 
-		# Parse the certificate information
-		foreach my $line (@cavalid) {
-			if ($line =~ /Not After : (.*)[\n]/) {
-				$expiryDate = &Date::Parse::str2time($1);
-				last;
-			}
-		}
+		# Disabled Connections
+		if ($status eq "off") {
+			$connstatus = "DISABLED";
 
-		# Calculate the remaining time
-		my $remainingTime = $expiryDate - time();
+		# N2N Connections
+		} elsif ($type eq "net") {
+			if (-e "/var/run/${name}n2n.pid") {
+				my $port = $confighash{$key}[22];
 
-		# Determine whether the certificate has already expired, or will so soon
-		$hasExpired = ($remainingTime <= 0);
-		$expiresSoon = ($remainingTime <= 30 * 24 * 3600);
+				if ($port ne "") {
+					$connstatus = &openvpn_status($confighash{$key}[22]);
+				}
+			}
 
-	} else {
-		# Populate booleans with dummy values for N2N connections (#13066)
-		$hasExpired = 0;
-		$expiresSoon = 0;
-	}
+		# RW Connections
+	    } elsif ($type eq "host") {
+			my $cn;
 
-	print "<tr>";
+			foreach my $line (@status) {
+				chomp($line);
 
-	if ($hasExpired || $expiresSoon) {
-		$col="bgcolor='$color{'color14'}'";
-	} elsif ($id % 2) {
-		$col="bgcolor='$color{'color20'}'";
-	} else {
-		$col="bgcolor='$color{'color22'}'";
-	}
-	print "<td align='center' nowrap='nowrap' $col>$confighash{$key}[1]";
-	if ($hasExpired) {
-		print " ($Lang::tr{'openvpn cert has expired'})";
-	} elsif ($expiresSoon) {
-		print " ($Lang::tr{'openvpn cert expires soon'})";
-	}
-	print "</td>";
-	print "<td align='center' nowrap='nowrap' $col>" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ")</td>";
-	print "<td align='center' $col>$confighash{$key}[25]</td>";
-	$col1="class='status is-disconnected'";
-	my $active = "$Lang::tr{'capsclosed'}";
-
-	if ($confighash{$key}[0] eq 'off') {
-		$col1="class='status is-disabled'";
-		$active = "$Lang::tr{'capsclosed'}";
-	} else {
+				if ($line =~ /^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/) {
+					my @match = split(m/^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/, $line);
 
-###
-# m.a.d net2net
-###
+					if ($match[1] ne "Common Name") {
+						$cn = $match[1];
+					}
 
-       if ($confighash{$key}[3] eq 'net') {
-
-        if (-e "/var/run/$confighash{$key}[1]n2n.pid") {
-          my @output = "";
-          my @tustate = "";
-          my $tport = $confighash{$key}[22];
-          my $tnet = new Net::Telnet ( Timeout=>5, Errmode=>'return', Port=>$tport);
-          if ($tport ne '') {
-          $tnet->open('127.0.0.1');
-          @output = $tnet->cmd(String => 'state', Prompt => '/(END.*\n|ERROR:.*\n)/');
-          @tustate = split(/\,/, $output[1]);
-###
-#CONNECTING    -- OpenVPN's initial state.
-#WAIT          -- (Client only) Waiting for initial response from server.
-#AUTH          -- (Client only) Authenticating with server.
-#GET_CONFIG    -- (Client only) Downloading configuration options from server.
-#ASSIGN_IP     -- Assigning IP address to virtual network interface.
-#ADD_ROUTES    -- Adding routes to system.
-#CONNECTED     -- Initialization Sequence Completed.
-#RECONNECTING  -- A restart has occurred.
-#EXITING       -- A graceful exit is in progress.
-####
-
-		if (($tustate[1] eq 'CONNECTED') || ($tustate[1] eq 'WAIT')) {
-			$col1="class='status is-connected'";
-			$active = "$Lang::tr{'capsopen'}";
-		}else {
-			$col1="class='status is-disconnected'";
-			$active = "$tustate[1]";
-		}
-           }
-           }
-        }else {
-
-				my $cn;
-				my @match = ();
-		foreach my $line (@status) {
-			chomp($line);
-			if ( $line =~ /^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/) {
-				@match = split(m/^(.+),(\d+\.\d+\.\d+\.\d+\:\d+),(\d+),(\d+),(.+)/, $line);
-				if ($match[1] ne "Common Name") {
-					$cn = $match[1];
-				}
-				if ($cn eq "$confighash{$key}[2]") {
-					$col1="class='status is-connected'";
-					$active = "$Lang::tr{'capsopen'}";
+					if ($cn eq "$confighash{$key}[2]") {
+						$connstatus = "CONNECTED";
+					}
 				}
 			}
-		}
-	}
-}
+	    }
 
+		if ($connstatus eq "DISABLED") {
+			print "<td class='status is-disabled'>$Lang::tr{'capsclosed'}</td>";
+		} elsif ($connstatus eq "CONNECTED") {
+			print "<td class='status is-connected'>$Lang::tr{'capsopen'}</td>";
+		} elsif ($connstatus eq "DISCONNECTED") {
+			print "<td class='status is-disconnected'>$Lang::tr{'capsclosed'}</td>";
+		} else {
+			print "<td class='status is-unknown'>$connstatus</td>";
+		}
 
-       if ($confighash{$key}[41] eq "pass") {
-               print <<END;
-                       <td align='center' $col1>$active</td>
+		# Download Configuration
+		print <<END;
+			<td class="text-center">
+				<form method='post' name='frm${key}a'>
+					<input type='image'  name='$Lang::tr{'dl client arch'}' src='/images/openvpn.png'
+						alt='$Lang::tr{'dl client arch'}' title='$Lang::tr{'dl client arch'}' />
+					<input type='hidden' name='ACTION' value='$Lang::tr{'dl client arch'}' />
+					<input type='hidden' name='KEY' value='$key' />
+				</form>
+			</td>
+END
 
-                       <form method='post' name='frm${key}a'><td align='center' $col>
-                           <input type='image'  name='$Lang::tr{'dl client arch'}' src='/images/openvpn_encrypted.png'
-                                       alt='$Lang::tr{'dl client arch'}' title='$Lang::tr{'dl client arch'}' border='0' />
-                           <input type='hidden' name='ACTION' value='$Lang::tr{'dl client arch'}' />
-                           <input type='hidden' name='MODE' value='secure' />
-                           <input type='hidden' name='KEY' value='$key' />
-                       </td></form>
+		# Show Certificate
+		if ($confighash{$key}[4] eq 'cert') {
+			print <<END;
+				<td class="text-center">
+					<form method='post' name='frm${key}b'>
+						<input type='image' name='$Lang::tr{'show certificate'}' src='/images/info.gif'
+							alt='$Lang::tr{'show certificate'}' title='$Lang::tr{'show certificate'}' />
+						<input type='hidden' name='ACTION' value='$Lang::tr{'show certificate'}' />
+						<input type='hidden' name='KEY' value='$key' />
+					</form>
+				</td>
 END
 
-       ; } elsif ($confighash{$key}[41] eq "no-pass") {
-		print <<END;
-                       <td align='center' $col1>$active</td>
+		} else {
+			print "<td></td>";
+		}
 
-                       <form method='post' name='frm${key}a'><td align='center' $col>
-				<input type='image'  name='$Lang::tr{'dl client arch insecure'}' src='/images/openvpn.png'
-					alt='$Lang::tr{'dl client arch insecure'}' title='$Lang::tr{'dl client arch insecure'}' border='0' />
-				<input type='hidden' name='ACTION' value='$Lang::tr{'dl client arch'}' />
-				<input type='hidden' name='MODE' value='insecure' />
-				<input type='hidden' name='KEY' value='$key' />
-			</td></form>
+		# Show OTP QR code
+		if ($confighash{$key}[43] eq 'on') {
+			print <<END;
+				<td class="text-center">
+					<form method='post' name='frm${key}o'>
+						<input type='image' name='$Lang::tr{'show otp qrcode'}' src='/images/qr-code.png'
+								alt='$Lang::tr{'show otp qrcode'}' title='$Lang::tr{'show otp qrcode'}' />
+						<input type='hidden' name='ACTION' value='$Lang::tr{'show otp qrcode'}' />
+						<input type='hidden' name='KEY' value='$key' />
+					</form>
+				</td>
 END
-	; } else {
-		print "<td $col>&nbsp;</td>";
-	}
+		} else {
+			print "<td></td>";
+		}
 
-	if ($confighash{$key}[4] eq 'cert') {
-	    print <<END;
-	    <form method='post' name='frm${key}b'><td align='center' $col>
-		<input type='image' name='$Lang::tr{'show certificate'}' src='/images/info.gif' alt='$Lang::tr{'show certificate'}' title='$Lang::tr{'show certificate'}' border='0' />
-		<input type='hidden' name='ACTION' value='$Lang::tr{'show certificate'}' />
-		<input type='hidden' name='KEY' value='$key' />
-	    </td></form>
+		# Download Certificate
+		if ($confighash{$key}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$key}[1].p12") {
+			print <<END;
+				<td class="text-center">
+					<form method='post' name='frm${key}c'>
+						<input type='image' name='$Lang::tr{'download pkcs12 file'}' src='/images/media-floppy.png'
+							alt='$Lang::tr{'download pkcs12 file'}' title='$Lang::tr{'download pkcs12 file'}' />
+						<input type='hidden' name='ACTION' value='$Lang::tr{'download pkcs12 file'}' />
+						<input type='hidden' name='KEY' value='$key' />
+					</form>
+				</td>
 END
-	; } else {
-	    print "<td>&nbsp;</td>";
-	}
 
-   if ($confighash{$key}[43] eq 'on') {
-      print <<END;
-<form method='post' name='frm${key}o'><td align='center' $col>
-<input type='image' name='$Lang::tr{'show otp qrcode'}' src='/images/qr-code.png' alt='$Lang::tr{'show otp qrcode'}' title='$Lang::tr{'show otp qrcode'}' border='0' />
-<input type='hidden' name='ACTION' value='$Lang::tr{'show otp qrcode'}' />
-<input type='hidden' name='KEY' value='$key' />
-</td></form>
+		} elsif ($confighash{$key}[4] eq 'cert') {
+			print <<END;
+				<td class="text-center">
+					<form method='post' name='frm${key}c'>
+						<input type='image' name='$Lang::tr{'download certificate'}' src='/images/media-floppy.png'
+							alt='$Lang::tr{'download certificate'}' title='$Lang::tr{'download certificate'}' />
+						<input type='hidden' name='ACTION' value='$Lang::tr{'download certificate'}' />
+						<input type='hidden' name='KEY' value='$key' />
+					</form>
+				</td>
 END
-; } else {
-      print "<td $col>&nbsp;</td>";
-   }
+		} else {
+			print "<td></td>";
+		}
 
-	if ($confighash{$key}[4] eq 'cert' && -f "${General::swroot}/ovpn/certs/$confighash{$key}[1].p12") {
-	    print <<END;
-	    <form method='post' name='frm${key}c'><td align='center' $col>
-		<input type='image' name='$Lang::tr{'download pkcs12 file'}' src='/images/media-floppy.png' alt='$Lang::tr{'download pkcs12 file'}' title='$Lang::tr{'download pkcs12 file'}' border='0' />
-		<input type='hidden' name='ACTION' value='$Lang::tr{'download pkcs12 file'}' />
-		<input type='hidden' name='KEY' value='$key' />
-	    </td></form>
-END
-	; } elsif ($confighash{$key}[4] eq 'cert') {
-	    print <<END;
-	    <form method='post' name='frm${key}c'><td align='center' $col>
-		<input type='image' name='$Lang::tr{'download certificate'}' src='/images/media-floppy.png' alt='$Lang::tr{'download certificate'}' title='$Lang::tr{'download certificate'}' border='0' />
-		<input type='hidden' name='ACTION' value='$Lang::tr{'download certificate'}' />
-		<input type='hidden' name='KEY' value='$key' />
-	    </td></form>
+		if ($status eq 'on') {
+			$gif = 'on.gif';
+		} else {
+			$gif = 'off.gif';
+		}
+
+		print <<END;
+			<td class="text-center">
+				<form method='post' name='frm${key}d'>
+					<input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif'
+						alt='$Lang::tr{'toggle enable disable'}' title='$Lang::tr{'toggle enable disable'}' />
+					<input type='hidden' name='ACTION' value='$Lang::tr{'toggle enable disable'}' />
+					<input type='hidden' name='KEY' value='$key' />
+				</form>
+			</td>
+
+			<td class="text-center">
+				<form method='post' name='frm${key}e'>
+					<input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' />
+					<input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif'
+						alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' />
+					<input type='hidden' name='KEY' value='$key' />
+				</form>
+			</td>
+
+			<td class="text-center">
+				<form method='post' name='frm${key}f'>
+					<input type='hidden' name='ACTION' value='$Lang::tr{'remove'}' />
+					<input type='image'  name='$Lang::tr{'remove'}' src='/images/delete.gif'
+						alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' />
+					<input type='hidden' name='KEY' value='$key' />
+				</form>
+			</td>
+		</tr>
 END
-	; } else {
-	    print "<td>&nbsp;</td>";
+
 	}
-	print <<END
-	<form method='post' name='frm${key}d'><td align='center' $col>
-	    <input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif' alt='$Lang::tr{'toggle enable disable'}' title='$Lang::tr{'toggle enable disable'}' border='0' />
-	    <input type='hidden' name='ACTION' value='$Lang::tr{'toggle enable disable'}' />
-	    <input type='hidden' name='KEY' value='$key' />
-	</td></form>
-
-	<form method='post' name='frm${key}e'><td align='center' $col>
-	    <input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' />
-	    <input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' width='20' height='20' border='0'/>
-	    <input type='hidden' name='KEY' value='$key' />
-	</td></form>
-	<form method='post' name='frm${key}f'><td align='center' $col>
-	    <input type='hidden' name='ACTION' value='$Lang::tr{'remove'}' />
-	    <input type='image'  name='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' width='20' height='20' border='0' />
-	    <input type='hidden' name='KEY' value='$key' />
-	</td></form>
-	</tr>
-END
-	;
-	$id++;
-	$lastnet = $confighash{$key}[32];
-    }
-    print"</table>";
-    ;
+	print"</table>";
 
-    # If the config file contains entries, print Key to action icons
-    if ( $id ) {
+	# Show controls
     print <<END;
-       <table width='85%' border='0'>
-       <tr>
-		<td class='boldbase'>&nbsp; <b>$Lang::tr{'legend'}:</b></td>
-              <td>&nbsp; &nbsp; <img src='/images/openvpn.png' alt='?RELOAD'/></td>
-              <td class='base'>$Lang::tr{'dl client arch insecure'}</td>
-              <td>&nbsp; &nbsp; <img src='/images/openvpn_encrypted.png' alt='?RELOAD'/></td>
-              <td class='base'>$Lang::tr{'dl client arch'}</td>
-		<td>&nbsp; &nbsp; <img src='/images/info.gif' alt='$Lang::tr{'show certificate'}' /></td>
-		<td class='base'>$Lang::tr{'show certificate'}</td>
-              <td>&nbsp; &nbsp; <img src='/images/qr-code.png' alt='$Lang::tr{'show otp qrcode'}'/></td>
-              <td class='base'>$Lang::tr{'show otp qrcode'}</td>
-       </tr>
-       <tr>
-              <td>&nbsp; </td>
-              <td>&nbsp; &nbsp; <img src='/images/media-floppy.png' alt='?FLOPPY' /></td>
-              <td class='base'>$Lang::tr{'download certificate'}</td>
-              <td>&nbsp; <img src='/images/off.gif' alt='?OFF' /></td>
-              <td class='base'>$Lang::tr{'click to enable'}</td>
-              <td>&nbsp; <img src='/images/on.gif' alt='$Lang::tr{'click to disable'}' /></td>
-              <td class='base'>$Lang::tr{'click to disable'}</td>		
-
-		<td>&nbsp; &nbsp; <img src='/images/edit.gif' alt='$Lang::tr{'edit'}' /></td>
-		<td class='base'>$Lang::tr{'edit'}</td>
-		<td>&nbsp; &nbsp; <img src='/images/delete.gif' alt='$Lang::tr{'remove'}' /></td>
-		<td class='base'>$Lang::tr{'remove'}</td>
-       </tr>
-       </table><br>
+		<table class="form">
+			<tr class="action">
+				<td>
+					<form method='post'>
+						<input type='submit' name='ACTION' value='$Lang::tr{'add'}' />
+						<input type='submit' name='ACTION' value='$Lang::tr{'ovpn con stat'}' />
+					</form>
+				</td>
+			</tr>
+		</table>
 END
-    ;
-    }
 
-    print <<END;
-    <table width='100%'>
-    <form method='post'>
-    <tr><td align='right'>
-		<input type='submit' name='ACTION' value='$Lang::tr{'add'}' />
-		<input type='submit' name='ACTION' value='$Lang::tr{'ovpn con stat'}' $activeonrun /></td>
-	</tr>
-    </form>
-    </table>
-END
-    ;
 	&Header::closebox();
-	}
 
     # CA/key listing
     &Header::openbox('100%', 'LEFT', "$Lang::tr{'certificate authorities'}");
@@ -5678,12 +5375,12 @@ END
     </tr>
 END
     ;
-    my $col1="bgcolor='$color{'color22'}'";
-    my $col2="bgcolor='$color{'color20'}'";
+    my $col1="bgcolor='$Header::color{'color22'}'";
+    my $col2="bgcolor='$Header::color{'color20'}'";
     # DH parameter line
-    my $col3="bgcolor='$color{'color22'}'";
+    my $col3="bgcolor='$Header::color{'color22'}'";
     # ta.key line
-    my $col4="bgcolor='$color{'color20'}'";
+    my $col4="bgcolor='$Header::color{'color20'}'";
 
     if (-f "${General::swroot}/ovpn/ca/cacert.pem") {
 		my @casubject = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/ca/cacert.pem");
@@ -5769,45 +5466,6 @@ END
 		;
     }
 
-    # Adding DH parameter to chart
-    if (-f "$dhparameter") {
-		my @dhsubject = &General::system_output("/usr/bin/openssl", "dhparam", "-text", "-in", "$dhparameter");
-		my $dhsubject;
-
-		foreach my $line (@dhsubject) {
-			if ($line =~ /    (.*)[\n]/) {
-				$dhsubject = $1;
-
-				last;
-			}
-		}
-
-	print <<END;
-		<tr>
-			<td class='base' $col3>$Lang::tr{'dh'}</td>
-			<td class='base' $col3>$dhsubject</td>
-			<form method='post' name='frmdhparam'><td width='3%' align='center' $col3>
-			<input type='hidden' name='ACTION' value='$Lang::tr{'show dh'}' />
-			<input type='image' name='$Lang::tr{'show dh'}' src='/images/info.gif' alt='$Lang::tr{'show dh'}' title='$Lang::tr{'show dh'}' width='20' height='20' border='0' />
-			</form>
-			<form method='post' name='frmdhparam'><td width='3%' align='center' $col3>
-			</form>
-			<td width='4%' $col3>&nbsp;</td>
-		</tr>
-END
-		;
-    } else {
-		# Nothing
-		print <<END;
-		<tr>
-			<td width='25%' class='base' $col3>$Lang::tr{'dh'}:</td>
-			<td class='base' $col3>$Lang::tr{'not present'}</td>
-			</td><td colspan='3' $col3>&nbsp;</td>
-		</tr>
-END
-		;
-    }
-
     # Adding ta.key to chart
     if (-f "${General::swroot}/ovpn/certs/ta.key") {
 		open(FILE, "${General::swroot}/ovpn/certs/ta.key");
@@ -5861,9 +5519,9 @@ END
     if (keys %cahash > 0) {
 		foreach my $key (keys %cahash) {
 			if (($key + 1) % 2) {
-				print "<tr bgcolor='$color{'color20'}'>\n";
+				print "<tr bgcolor='$Header::color{'color20'}'>\n";
 			} else {
-				print "<tr bgcolor='$color{'color22'}'>\n";
+				print "<tr bgcolor='$Header::color{'color22'}'>\n";
 			}
 			print "<td class='base'>$cahash{$key}[0]</td>\n";
 			print "<td class='base'>$cahash{$key}[1]</td>\n";
@@ -5934,7 +5592,7 @@ END
 END
 	;
 
-    if ( $srunning eq "yes" ) {
+    if ($vpnsettings{'ENABLED'} eq "yes") {
 		print "<div align='center'><form method='post'><input type='submit' name='ACTION' value='$Lang::tr{'remove x509'}' disabled='disabled' /></div></form>\n";
     } else {
 		print "<div align='center'><form method='post'><input type='submit' name='ACTION' value='$Lang::tr{'remove x509'}' /></div></form>\n";
diff --git a/html/cgi-bin/services.cgi b/html/cgi-bin/services.cgi
index 462b6bfa1a..8b92f7e082 100644
--- a/html/cgi-bin/services.cgi
+++ b/html/cgi-bin/services.cgi
@@ -2,7 +2,7 @@
 ###############################################################################
 #                                                                             #
 # IPFire.org - A linux based firewall                                         #
-# Copyright (C) 2005-2021  IPFire Team                                        #
+# Copyright (C) 2005-2025  IPFire Team                                        #
 #                                                                             #
 # This program is free software: you can redistribute it and/or modify        #
 # it under the terms of the GNU General Public License as published by        #
@@ -114,7 +114,7 @@ $querry[1] = 'hour' unless defined $querry[1];
 		# OpenVPN Roadwarrior
 		$Lang::tr{'ovpn roadwarrior server'} => {
 			"process" => "openvpn",
-			"pidfile" => "/var/run/openvpn.pid",
+			"pidfile" => "/var/run/openvpn-rw.pid",
 		}
 	});
 
diff --git a/html/cgi-bin/tor.cgi b/html/cgi-bin/tor.cgi
index 9aa2bc95a1..cfad229e12 100644
--- a/html/cgi-bin/tor.cgi
+++ b/html/cgi-bin/tor.cgi
@@ -241,26 +241,11 @@ sub showMainBox() {
 
 	&Header::openbox('100%', 'center', $Lang::tr{'tor'});
 
-
-if ( ($memory != 0) && (@pid[0] ne "///") ){
-		print "<table width='95%' cellspacing='0' class='tbl'>";
-		print "<tr><th bgcolor='$color{'color20'}' colspan='3' align='left'><strong>$Lang::tr{'tor service'}</strong></th></tr>";
-		print "<tr><td class='base'>$Lang::tr{'tor daemon'}</td>";
-		print "<td align='center' colspan='2' width='75%' bgcolor='${Header::colourgreen}'><font color='white'><strong>$Lang::tr{'running'}</strong></font></td></tr>";
-		print "<tr><td class='base'></td>";
-		print "<td bgcolor='$color{'color20'}' align='center'><strong>PID</strong></td>";
-		print "<td bgcolor='$color{'color20'}' align='center'><strong>$Lang::tr{'memory'}</strong></td></tr>";
-		print "<tr><td class='base'></td>";
-		print "<td bgcolor='$color{'color22'}' align='center'>@pid[0]</td>";
-		print "<td bgcolor='$color{'color22'}' align='center'>$memory KB</td></tr>";
-		print "</table>";
-	} else {
-		print "<table width='95%' cellspacing='0' class='tbl'>";
-		print "<tr><th bgcolor='$color{'color20'}' colspan='3' align='left'><strong>$Lang::tr{'tor service'}</strong></th></tr>";
-		print "<tr><td class='base'>$Lang::tr{'tor daemon'}</td>";
-		print "<td align='center' width='75%' bgcolor='${Header::colourred}'><font color='white'><strong>$Lang::tr{'stopped'}</strong></font></td></tr>";
-		print "</table>";
-	}
+	&Header::ServiceStatus({
+		$Lang::tr{'tor service'} => {
+			"process" => "tor",
+		}
+	});
 
 	&Header::closebox();
 
diff --git a/html/cgi-bin/vulnerabilities.cgi b/html/cgi-bin/vulnerabilities.cgi
index a98eb7b004..cab38d8de4 100644
--- a/html/cgi-bin/vulnerabilities.cgi
+++ b/html/cgi-bin/vulnerabilities.cgi
@@ -96,7 +96,7 @@ if ($notice) {
 	&Header::closebox();
 }
 
-&Header::openbox('100%', 'center', $Lang::tr{'processor vulnerability mitigations'});
+&Header::opensection();
 
 print <<END;
 	<table class="tbl">
@@ -159,7 +159,7 @@ print <<END;
 	</table>
 END
 
-&Header::closebox();
+&Header::closesection();
 
 print "<form method='post' action='$ENV{'SCRIPT_NAME'}'>\n";
 
diff --git a/html/html/themes/ipfire/include/css/style.css b/html/html/themes/ipfire/include/css/style.css
index c598893261..df6ee6b47f 100644
--- a/html/html/themes/ipfire/include/css/style.css
+++ b/html/html/themes/ipfire/include/css/style.css
@@ -106,6 +106,10 @@ h6 {
 	font-size: 1em;
 }
 
+select, textarea {
+	width: 100%;
+}
+
 br.clear {
 	clear: both;
 }
@@ -386,6 +390,12 @@ table.form tr.header td {
 	margin-top: 1rem;
 }
 
+table.form tr.header td {
+	font-weight: bold;
+
+	margin-top: 1rem;
+}
+
 table.form tr.action td {
 	padding-top: 1rem;
 
@@ -400,6 +410,11 @@ table.form tr.action td form {
 	width: 100%;
 }
 
+.tbl tr.is-warning td {
+	color: var(--color-yellow-invert) !important;
+	background-color: var(--color-yellow) !important;
+}
+
 .tbl th {
 	color: #ffffff;
 	border-top: 1px solid #363636;
@@ -407,6 +422,9 @@ table.form tr.action td form {
 	background: #363636;
 	padding-left: 0.5em;
 	padding-right: 0.5em;
+
+	text-align: center;
+	font-weight: bold;
 }
 
 .tbl th[scope=row] {
@@ -513,7 +531,7 @@ table.form tr.action td form {
 	color: var(--color-red-invert);
 }
 
-.tbl .status.is-disabled, .tbl .status.is-mitigation {
+.tbl .status.is-mitigation, .tbl .status.is-disabled {
 	background-color: var(--color-blue);
 	color: var(--color-blue-invert);
 }
diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl
index a05b6056db..22ab0bad10 100644
--- a/langs/en/cgi-bin/en.pl
+++ b/langs/en/cgi-bin/en.pl
@@ -2,12 +2,17 @@
 %tr,
 
 '24 hours' => '24 Hours',
+'AES-128-CBC' => 'AES - CBC Mode - 128 Bit',
+'AES-128-GCM' => 'AES - GCM Mode - 128 Bit',
+'AES-256-CBC' => 'AES - CBC Mode - 256 Bit',
+'AES-256-GCM' => 'AES - GCM Mode - 256 Bit',
 'Act as' => 'Act as:',
 'Add Level7 rule' => 'Add Level7 rule',
 'Add Port Rule' => 'Add port rule',
 'Add Rule' => 'Add rule',
 'Add a route' => 'Add a route',
 'Async logging enabled' => 'Enable asynchronous writing of the syslog file',
+'CHACHA20-POLY1305' => 'ChaCha20-Poly1305',
 'Captive' => 'Captive Portal',
 'Captive 1day' => '1 day',
 'Captive 1month' => '1 month',
@@ -166,7 +171,7 @@
 'administrator username' => 'Administrator username',
 'adsl settings' => 'ADSL settings',
 'advanced' => 'Advanced',
-'advanced server' => 'Advanced server options',
+'advanced server' => 'Advanced Settings',
 'advproxy AUTH always required' => 'Require authentication for unrestricted source addresses',
 'advproxy AUTH auth cache TTL' => 'Authentication cache TTL (in minutes)',
 'advproxy AUTH global settings' => 'Global authentication settings',
@@ -792,7 +797,7 @@
 'destination ip bad' => 'Invalid destination IP',
 'destination ip or net' => 'Destination IP or net',
 'destination net' => 'Destination Net',
-'destination port' => 'Destination port',
+'destination port' => 'Destination Port',
 'destination port numbers' => 'Destination port must be a valid port number or port range.',
 'destination port overlaps' => 'Destination port range overlaps an existing port range.',
 'detail level' => 'Detail level',
@@ -839,7 +844,6 @@
 'dhcp server enabled' => 'DHCP server enabled.  Restarting.',
 'dhcp server enabled on blue interface' => 'DHCP server enabled on BLUE interface',
 'dhcp valid range required when deny known clients checked' => 'Valid range required when "Deny known clients:" is checked',
-'dhcp-options' => 'DHCP push options',
 'dial' => 'Connect',
 'dial profile' => 'Connect with profile',
 'dial user password' => 'Dial user password:',
@@ -861,8 +865,7 @@
 'display hostname in window title' => 'Display hostname in window title',
 'display traffic at home' => 'Display calculated traffic on startpage',
 'display webinterface effects' => 'Activate effects',
-'dl client arch' => 'Download Encrypted Client Package (zip)',
-'dl client arch insecure' => 'Download insecure Client Package (zip)',
+'dl client arch' => 'Download Client Configuration',
 'dmz' => 'DMZ',
 'dmz pinhole configuration' => 'DMZ pinhole configuration',
 'dmz pinhole rule added' => 'DMZ pinhole rule added; restarting DMZ pinhole',
@@ -1825,7 +1828,6 @@
 'minimum' => 'Minimum',
 'minute' => 'Minute',
 'minutes' => 'Minutes',
-'misc-options' => 'Miscellaneous options',
 'missing dat' => 'Encrypted archive not found',
 'missing gz' => 'Unencrypted archive not found',
 'mitigated' => 'Mitigated',
@@ -2034,20 +2036,28 @@
 'override mtu' => 'Override default MTU',
 'ovpn' => 'OpenVPN',
 'ovpn add conf' => 'Additional configuration',
+'ovpn ciphers' => 'Ciphers',
 'ovpn con stat' => 'OpenVPN Connection Statistics',
 'ovpn config' => 'OVPN-Config',
 'ovpn connection name' => 'Connection Name',
-'ovpn crypt options' => 'Cryptographic options',
+'ovpn crypto settings' => 'Cryptographic Settings',
 'ovpn device' => 'OpenVPN device:',
+'ovpn dhcp settings' => 'DHCP Settings',
 'ovpn dl' => 'OVPN-Config Download',
+'ovpn dynamic client subnet' => 'Dynamic Client Subnet',
 'ovpn engines' => 'Crypto engine',
 'ovpn errmsg green already pushed' => 'Route for green network is always set',
 'ovpn errmsg invalid ip or mask' => 'Invalid network-address or subnetmask',
+'ovpn errmsg invalid route' => 'Invalid route',
 'ovpn error md5' => 'You host certificate uses MD5 for the signature which is not accepted anymore. <br>Please update to the latest IPFire version and generate a new root and host certificate.</br><br>All OpenVPN clients needs then to be renewed!</br>',
+'ovpn fallback cipher' => 'Fallback Cipher',
+'ovpn fallback cipher help' => 'This cipher is being used by clients that do not support cipher negotiation.',
+'ovpn fqdn' => 'FQDN',
 'ovpn generating the root and host certificates' => 'Generating the root and host certificate can take a long time.',
 'ovpn ha' => 'Hash algorithm',
 'ovpn log' => 'OVPN-Log',
 'ovpn mgmt in root range' => 'A port number of 1024 or higher is required.',
+'ovpn misc settings' => 'Miscellaneous Settings',
 'ovpn mtu-disc' => 'Path MTU Discovery',
 'ovpn mtu-disc and mtu not 1500' => 'Path MTU Discovery requires a MTU of 1500.',
 'ovpn mtu-disc maybe' => 'Optionally',
@@ -2055,21 +2065,27 @@
 'ovpn mtu-disc off' => 'Disabled',
 'ovpn mtu-disc with mssfix or fragment' => 'Path MTU Discovery cannot be used with mssfix or fragment.',
 'ovpn mtu-disc yes' => 'Forced',
+'ovpn no cipher selected' => 'No cipher selected',
 'ovpn no connections' => 'No active OpenVPN connections',
 'ovpn on blue' => 'OpenVPN on BLUE:',
 'ovpn on orange' => 'OpenVPN on ORANGE:',
 'ovpn on red' => 'OpenVPN on RED:',
 'ovpn port in root range' => 'A port number of 1024 or higher is required.',
+'ovpn protocol settings' => 'Protocol Settings',
+'ovpn push default route' => 'Push Default Route',
 'ovpn reneg sec' => 'Session key lifetime:',
 'ovpn roadwarrior server' => 'OpenVPN Roadwarrior Server',
-'ovpn routes push' => 'Routes (one per line) e.g. 192.168.10.0/255.255.255.0 192.168.20.0/24',
-'ovpn routes push options' => 'Route push options',
+'ovpn roadwarrior settings' => 'Roadwarrior Settings',
+'ovpn routes push' => 'Custom Routes',
+'ovpn routing settings' => 'Routing Settings',
 'ovpn rw connection log' => 'OpenVPN Roadwarrior Connections Log',
 'ovpn server status' => 'Current OpenVPN server status:',
 'ovpn subnet' => 'OpenVPN subnet:',
 'ovpn subnet is invalid' => 'OpenVPN subnet is invalid.',
 'ovpn subnet overlap' => 'OpenVPN Subnet overlaps with : ',
 'ovpn tls auth' => 'TLS Channel Protection:',
+'ovpn transport protocol' => 'Transport Protocol',
+'ovpn unsupported cipher selected' => 'Unknown cipher selected',
 'ovpn warning rfc3280' => 'Your host certificate is not RFC3280 compliant. <br>Please update to the latest IPFire version and generate as soon as possible a new root and host certificate.</br><br>All OpenVPN clients needs then to be renewed!</br>',
 'ovpn_fastio' => 'Fast-IO',
 'ovpn_mssfix' => 'MSSFIX Size',
@@ -2300,6 +2316,8 @@
 'router ip' => 'Router IP address:',
 'routing' => 'Routing',
 'routing table entries' => 'Routing Table Entries',
+'rss' => 'RSS',
+'rss long' => 'Resident Set Size',
 'rsvd dst port overlap' => 'Destination Port Range overlaps a port reserved for IPFire:',
 'rsvd src port overlap' => 'Source Port Range overlaps a port reserved for IPFire:',
 'rules already up to date' => 'Rules already up to date',
@@ -2317,7 +2335,7 @@
 'save config' => 'save settings',
 'save error' => 'Unable to save configuration archive file',
 'save settings' => 'Save settings',
-'save-adv-options' => 'Save advanced options',
+'save-adv-options' => 'Save Advanced Settings',
 'scanned' => 'Scanned',
 'script name' => 'Script name:',
 'search' => 'Search',
diff --git a/lfs/initscripts b/lfs/initscripts
index 700e912445..99fe2f1be4 100644
--- a/lfs/initscripts
+++ b/lfs/initscripts
@@ -95,6 +95,8 @@ $(TARGET) :
 	ln -sf ../init.d/vdradmin		/etc/rc.d/rc0.d/K01vdradmin
 	ln -sf ../init.d/fcron			/etc/rc.d/rc0.d/K08fcron
 	ln -sf ../init.d/apache			/etc/rc.d/rc0.d/K28apache
+	ln -sf ../init.d/openvpn-rw		/etc/rc.d/rc0.d/K10openvpn-rw
+	ln -sf ../init.d/openvpn-n2n		/etc/rc.d/rc0.d/K11openvpn-n2n
 	ln -sf ../init.d/sshd			/etc/rc.d/rc0.d/K30sshd
 	ln -sf ../init.d/setclock		/etc/rc.d/rc0.d/K47setclock
 	ln -sf  ../init.d/cyrus-sasl		/etc/rc.d/rc0.d/K49cyrus-sasl
@@ -129,6 +131,8 @@ $(TARGET) :
 	ln -sf ../init.d/sshd			/etc/rc.d/rc3.d/S30sshd
 	ln -sf ../init.d/apache			/etc/rc.d/rc3.d/S32apache
 	ln -sf ../init.d/fcron			/etc/rc.d/rc3.d/S40fcron
+	ln -sf ../init.d/openvpn-n2n		/etc/rc.d/rc3.d/S51openvpn-n2n
+	ln -sf ../init.d/openvpn-rw		/etc/rc.d/rc3.d/S50openvpn-rw
 	ln -sf ../init.d/wireguard		/etc/rc.d/rc3.d/S50wireguard
 	ln -sf ../../sysconfig/rc.local		/etc/rc.d/rc3.d/S98rc.local
 	ln -sf ../init.d/grub-btrfsd		/etc/rc.d/rc3.d/S99grub-btrfsd
@@ -137,6 +141,8 @@ $(TARGET) :
 	ln -sf ../init.d/grub-btrfsd		/etc/rc.d/rc6.d/K01grub-btrfsd
 	ln -sf ../init.d/vdradmin		/etc/rc.d/rc6.d/K01vdradmin
 	ln -sf ../init.d/fcron			/etc/rc.d/rc6.d/K08fcron
+	ln -sf ../init.d/openvpn-rw		/etc/rc.d/rc6.d/K10openvpn-rw
+	ln -sf ../init.d/openvpn-n2n		/etc/rc.d/rc6.d/K11openvpn-n2n
 	ln -sf ../init.d/apache			/etc/rc.d/rc6.d/K28apache
 	ln -sf ../init.d/sshd			/etc/rc.d/rc6.d/K30sshd
 	ln -sf ../init.d/setclock		/etc/rc.d/rc6.d/K47setclock
diff --git a/lfs/openvpn b/lfs/openvpn
index 807019f0a1..e66b50c2e5 100644
--- a/lfs/openvpn
+++ b/lfs/openvpn
@@ -24,7 +24,7 @@
 
 include Config
 
-VER        = 2.5.10
+VER        = 2.6.14
 
 THISAPP    = openvpn-$(VER)
 DL_FILE    = $(THISAPP).tar.gz
@@ -40,7 +40,7 @@ objects = $(DL_FILE)
 
 $(DL_FILE) = $(DL_FROM)/$(DL_FILE)
 
-$(DL_FILE)_BLAKE2 = 7f4ae82162e2e48e66df2da8008f45a2db53a22483730808b873948f1dc13a2e5582c79e4469f9d794f8b0f87f08d627e8d1bd070b088ea33444af31779f5479
+$(DL_FILE)_BLAKE2 = 15376d0a1600abfbf8541614282c622bbc09bf4402730a20eb6606bf1debdda0836e069fd45068bda1d71deb72df052c68425771693592d3c72d680a16c87d6d
 
 install : $(TARGET)
 
diff --git a/lfs/tor b/lfs/tor
index 980c1a8f5a..0d57f5fed9 100644
--- a/lfs/tor
+++ b/lfs/tor
@@ -34,7 +34,7 @@ DL_FROM    = $(URL_IPFIRE)
 DIR_APP    = $(DIR_SRC)/$(THISAPP)
 TARGET     = $(DIR_INFO)/$(THISAPP)
 PROG       = tor
-PAK_VER    = 88
+PAK_VER    = 89
 
 DEPS       = libseccomp
 
diff --git a/src/initscripts/networking/red.down/10-ovpn b/src/initscripts/networking/red.down/10-ovpn
deleted file mode 100644
index 948d7b276a..0000000000
--- a/src/initscripts/networking/red.down/10-ovpn
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-
-/usr/local/bin/openvpnctrl -k &
-/usr/local/bin/openvpnctrl -kn2n &
-
-exit 0
diff --git a/src/initscripts/networking/red.up/50-ovpn b/src/initscripts/networking/red.up/50-ovpn
deleted file mode 100644
index f3db648bc1..0000000000
--- a/src/initscripts/networking/red.up/50-ovpn
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-
-/usr/local/bin/openvpnctrl -s > /dev/null 2>&1
-/usr/local/bin/openvpnctrl -sn2n > /dev/null 2>&1
-
-exit 0
diff --git a/src/initscripts/system/firewall b/src/initscripts/system/firewall
index 0d5bb00615..304c7c3cc9 100644
--- a/src/initscripts/system/firewall
+++ b/src/initscripts/system/firewall
@@ -332,9 +332,13 @@ iptables_init() {
 	iptables -N WGINPUT
 	iptables -A INPUT -j WGINPUT
 
-	# OpenVPN
-	iptables -N OVPNINPUT
-	iptables -A INPUT -j OVPNINPUT
+	# OpenVPN Roadwarrior
+	iptables -N OVPNINPUTRW
+	iptables -A INPUT -j OVPNINPUTRW
+
+	# OpenVPN N2N
+	iptables -N OVPNINPUTN2N
+	iptables -A INPUT -j OVPNINPUTN2N
 
 	# Tor (outbound)
 	iptables -N TOR_OUTPUT
@@ -419,8 +423,8 @@ iptables_init() {
 	# Populate IPsec chains
 	/usr/lib/firewall/ipsec-policy
 
-	# Apply OpenVPN firewall rules
-	/usr/local/bin/openvpnctrl --firewall-rules
+	# Apply OpenVPN N2N firewall rules
+	/etc/rc.d/init.d/openvpn-n2n firewall-rules
 
 	# run wirelessctrl
 	/usr/local/bin/wirelessctrl
diff --git a/src/initscripts/system/functions b/src/initscripts/system/functions
index 94c9236d3f..85eb3e975b 100644
--- a/src/initscripts/system/functions
+++ b/src/initscripts/system/functions
@@ -369,7 +369,7 @@ pidofproc()
 		for pid in ${lpids}
 		do
 			if [ "${pid}" -ne "$$" -a "${pid}" -ne "${PPID}" ]; then
-				kill -0 "${pid}" > /dev/null &&
+				kill -0 "${pid}" 2> /dev/null &&
 				pidlist="${pidlist} ${pid}"
 			fi
 			
diff --git a/src/initscripts/system/openvpn-n2n b/src/initscripts/system/openvpn-n2n
new file mode 100644
index 0000000000..4d55f4cbd5
--- /dev/null
+++ b/src/initscripts/system/openvpn-n2n
@@ -0,0 +1,372 @@
+#!/bin/sh
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2007-2022  IPFire Team  <info@ipfire.org>                     #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+. /etc/sysconfig/rc
+. ${rc_functions}
+
+# Include network functions
+. /etc/init.d/networking/functions.network
+
+update_firewall_rules() {
+	local id
+	local enabled
+	local name
+	local x3
+	local type
+	local x5
+	local x6
+	local role
+	local x8
+	local local_subnet
+	local x10
+	local x11
+	local x12
+	local x13
+	local x14
+	local x15
+	local x16
+	local x17
+	local x18
+	local x19
+	local x20
+	local x21
+	local x22
+	local x23
+	local x24
+	local x25
+	local x26
+	local x27
+	local transfer_subnet
+	local proto
+	local port
+	local rest
+
+	local transfer_address
+	local local_address
+
+	# Flush the block chain
+	iptables -F OVPNBLOCK
+
+	# Flush the NAT chain
+	iptables -t nat -F OVPNNAT
+
+	local IFS=','
+
+	# Read all connections
+	while read -r id enabled name x3 type x5 x6 role x8 local_subnet x10 \
+			x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 \
+			x26 x27 transfer_subnet proto port rest; do
+		# Skip all disabled connections
+		if [ "${enabled}" != "on" ]; then
+			continue
+		fi
+
+		# Skip all connections that are not of type 'net'
+		if [ "${type}" != "net" ]; then
+			continue
+		fi
+
+		# Open port
+		iptables -A OVPNINPUTN2N -p "${proto}" --dport "${port}" -j ACCEPT
+
+		# Block all communication from transfer networks
+		iptables -A OVPNBLOCK -s "${transfer_subnet}" -j DROP
+
+		# Calculate NAT addresses
+		transfer_address="$(calculate_transfer_address "${transfer_subnet}" "${role}")"
+		local_address="$(calculate_local_address "${local_subnet}")"
+
+		# NAT all outgoing connections away from the transfer net
+		if [ -n "${transfer_address}" -a -n "${local_address}" ]; then
+			iptables -t nat -A OVPNNAT -s "${transfer_address}" \
+				-j SNAT --to-source "${local_address}"
+		fi
+	done < /var/ipfire/ovpn/ovpnconfig
+}
+
+calculate_transfer_address() {
+	local network="${1}"
+	local role="${2}"
+
+	local address="$(network_get_address "${network}")"
+	local netmask="$(network_get_netmask "${network}")"
+
+	# Convert everything to binary
+	address="$(ip2bin "${address}")"
+	netmask="$(ip2bin "${netmask}")"
+
+	# Make sure the address is the first address of the network
+	(( address &= netmask ))
+
+	case "${role}" in
+		server)
+			(( address += 1 ))
+			;;
+
+		client)
+			(( address += 2 ))
+			;;
+
+		# Exit on any invalid role
+		*)
+			return 1
+			;;
+	esac
+
+	# Return the address
+	bin2ip "${address}"
+}
+
+calculate_local_address() {
+	local network="${1}"
+
+	local addresses=(
+		# GREEN
+		"${GREEN_ADDRESS}"
+
+		# BLUE
+		"${BLUE_ADDRESS}"
+
+		# ORANGE
+		"${ORANGE_ADDRESS}"
+	)
+
+	local address
+	for address in "${addresses[@]}"; do
+		if network_address_in_network "${address}" "${network}"; then
+			echo "${address}"
+			return 0
+		fi
+	done
+
+	return 1
+}
+
+all_connections() {
+	local command="${1}"
+	shift
+
+	local id
+	local enabled
+	local name
+	local x3
+	local type
+	local rest
+
+	local IFS=,
+
+	# Read all connections
+	while read -r id enabled name x3 type rest; do
+		# Filter for all connections that of type 'net'
+		case "${type}" in
+			net)
+				# Check if the connection is in the filter list
+				if [ $# -gt 0 ]; then
+					local found=0
+
+					local n
+					for n in $@; do
+						if [ "${name}" = "${n}" ]; then
+							found=1
+							break
+						fi
+					done
+
+					# Skip this connection if not found
+					if [ "${found}" -eq 0 ]; then
+						continue
+					fi
+				fi
+
+				# Run the command
+				"${command}" "${name}"
+				;;
+		esac
+	done < /var/ipfire/ovpn/ovpnconfig
+}
+
+start_connections() {
+	local connection
+	local failed=0
+
+	for connection in $@; do
+		start "${connection}" || failed=1
+	done
+
+	return "${failed}"
+}
+
+start() {
+	local name="${1}"
+
+	local id
+	local enabled
+	local _name
+	local rest
+
+	local IFS=,
+
+	# Read the connection
+	while read -r id enabled _name rest; do
+		if [ "${name}" = "${_name}" ]; then
+			if [ "${enabled}" = "on" ]; then
+				break
+
+			# Log an error if the connection is not enabled
+			else
+				boot_mesg "OpenVPN N2N connection '${name}' is not enabled" "${WARNING}"
+				echo_warning
+
+				return 0
+			fi
+		fi
+	done < /var/ipfire/ovpn/ovpnconfig
+
+	# Create path to the configuration file
+	local config="/var/ipfire/ovpn/n2nconf/${name}/${name}.conf"
+
+	# Check if the connection exists
+	if [ ! -r "${config}" ]; then
+		boot_mesg "OpenVPN N2N connection '${name}' does not exist" "${FAILURE}"
+		echo_failure
+
+		return 1
+	fi
+
+	# Load the tun module
+	modprobe tun
+
+	boot_mesg "Starting OpenVPN N2N connection '${name}'..."
+
+	PIDFILE="/var/run/${name}n2n.pid" \
+		loadproc -f /usr/sbin/openvpn --config "${config}"
+}
+
+stop() {
+	local name="${1}"
+
+	boot_mesg "Stopping OpenVPN N2N connection '${name}'..."
+
+	PIDFILE="/var/run/${name}n2n.pid" \
+		killproc /usr/sbin/openvpn
+}
+
+reload() {
+	local name="${1}"
+
+	boot_mesg "Reloading OpenVPN N2N connection '${name}'..."
+
+	PIDFILE="/var/run/${name}n2n.pid" \
+		reloadproc /usr/sbin/openvpn
+}
+
+status() {
+	local name="${1}"
+
+	local pidlist
+
+	PIDFILE="/var/run/${name}n2n.pid" getpids "/usr/bin/openvpn"
+
+	if [ -n "${pidlist}" ]; then
+		echo -e "${INFO}Connection '${name}' is running with Process ID(s) ${pidlist}.${NORMAL}"
+	else
+		echo -e "${INFO}Connection '${name}' is not running.${NORMAL}"
+		return 1
+	fi
+}
+
+delete() {
+	local name="${1}"
+
+	local id
+	local enabled
+	local _name
+	local x3
+	local type
+	local rest
+
+	local IFS=,
+
+	# Read the connection
+	while read -r id enabled _name x3 type rest; do
+		if [ "${name}" = "${_name}" ]; then
+			case "${type}" in
+				host)
+					rm -rf "/var/log/rrd/collectd/localhost/openvpn-${name}/"
+					;;
+
+				net)
+					rm -rf "/var/log/rrd/collectd/localhost/openvpn-${name}-n2n/"
+					;;
+			esac
+		fi
+	done < /var/ipfire/ovpn/ovpnconfig
+}
+
+case "${1}" in
+	start)
+		# Update all firewall rules
+		update_firewall_rules
+
+		# Start all connections
+		all_connections start "${@:2}"
+		;;
+
+	stop)
+		# Update all firewall rules
+		update_firewall_rules
+
+		# Stop all connections
+		all_connections stop "${@:2}"
+		;;
+
+	reload)
+		# Update all firewall rules
+		update_firewall_rules
+
+		# Reload all connections
+		all_connections reload "${@:2}"
+		;;
+
+	restart)
+		${0} stop
+		sleep 1
+		${0} start
+		;;
+
+	status)
+		# Show the status of all connections
+		all_connections status "${@:2}"
+		;;
+
+	firewall-rules)
+		update_firewall_rules
+		;;
+
+	delete)
+		delete "${2}"
+		;;
+
+	*)
+		echo "Usage: ${0} {start|stop|reload|restart|status}"
+		exit 1
+		;;
+esac
diff --git a/src/initscripts/system/openvpn-rw b/src/initscripts/system/openvpn-rw
new file mode 100644
index 0000000000..56a62d71cc
--- /dev/null
+++ b/src/initscripts/system/openvpn-rw
@@ -0,0 +1,86 @@
+#!/bin/sh
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2007-2022  IPFire Team  <info@ipfire.org>                     #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+. /etc/sysconfig/rc
+. ${rc_functions}
+
+PIDFILE="/var/run/openvpn-rw.pid"
+
+# Load configuration
+eval $(/usr/local/bin/readhash /var/ipfire/ovpn/settings)
+
+case "${1}" in
+	start)
+		# Exit if OpenVPN is not enabled
+		if [ "${ENABLED}" != "on" ]; then
+			exit 0
+		fi
+
+		# Load the tun module
+		modprobe tun
+
+		# Flush all firewall rules
+		iptables -F OVPNINPUTRW
+
+		# Open the port
+		iptables -A OVPNINPUTRW \
+			-p "${DPROTOCOL}" --dport "${DDEST_PORT}" -j ACCEPT
+
+		boot_mesg "Starting OpenVPN Roadwarrior Server..."
+		loadproc -f /usr/sbin/openvpn \
+			--config /var/ipfire/ovpn/server.conf
+
+		boot_mesg "Starting OpenVPN Authenticator..."
+		PIDFILE= loadproc /usr/sbin/openvpn-authenticator --daemon
+		;;
+
+	stop)
+		boot_mesg "Stopping OpenVPN Authenticator..."
+		PIDFILE= killproc /usr/sbin/openvpn-authenticator
+
+		boot_mesg "Stopping OpenVPN Roadwarrior Server..."
+		killproc /usr/sbin/openvpn
+
+		# Flush all firewall rules
+		iptables -F OVPNINPUTRW
+		;;
+
+	restart)
+		${0} stop
+		sleep 1
+		${0} start
+		;;
+
+	status)
+		statusproc /usr/sbin/openvpn
+		;;
+
+	log)
+		if [ -r "/var/run/openvpn-rw.log" ]; then
+			cat "/var/run/openvpn-rw.log"
+		fi
+		;;
+
+	*)
+		echo "Usage: ${0} {start|stop|reload|restart|status}"
+		exit 1
+		;;
+esac
diff --git a/src/misc-progs/openvpnctrl.c b/src/misc-progs/openvpnctrl.c
index fb32146e43..cd2a9ca4d6 100644
--- a/src/misc-progs/openvpnctrl.c
+++ b/src/misc-progs/openvpnctrl.c
@@ -1,779 +1,41 @@
-#define _DEFAULT_SOURCE
-#define _XOPEN_SOURCE 500
-#include <signal.h>
+/* This file is part of the IPFire Firewall.
+ *
+ * This program is distributed under the terms of the GNU General Public
+ * Licence.  See the file COPYING for details.
+ *
+ */
+
 #include <stdio.h>
 #include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <fcntl.h>
-#include <ftw.h>
-#include "setuid.h"
-#include "netutil.h"
-#include "libsmooth.h"
-
-#define noovpndebug
-
-// global vars
-	struct keyvalue *kv = NULL;
-	FILE *ifacefile = NULL;
-
-char redif[STRING_SIZE];
-char blueif[STRING_SIZE];
-char orangeif[STRING_SIZE];
-char enablered[STRING_SIZE] = "off";
-char enableblue[STRING_SIZE] = "off";
-char enableorange[STRING_SIZE] = "off";
-
-// consts
-char OVPNINPUT[STRING_SIZE] = "OVPNINPUT";
-char OVPNBLOCK[STRING_SIZE] = "OVPNBLOCK";
-char OVPNNAT[STRING_SIZE] = "OVPNNAT";
-char WRAPPERVERSION[STRING_SIZE] = "ipfire-2.2.4";
-
-struct connection_struct {
-	char name[STRING_SIZE];
-	char type[STRING_SIZE];
-	char proto[STRING_SIZE];
-	char status[STRING_SIZE];
-	char local_subnet[STRING_SIZE];
-	char transfer_subnet[STRING_SIZE];
-	char role[STRING_SIZE];
-	char port[STRING_SIZE];
-	struct connection_struct *next;
-};
-
-typedef struct connection_struct connection;
-
-static int recursive_remove_callback(const char* fpath, const struct stat* sb, int typeflag, struct FTW* ftwbuf) {
-	int rv = remove(fpath);
-	if (rv)
-		perror(fpath);
-
-	return rv;
-}
-
-static int recursive_remove(const char* path) {
-	return nftw(path, recursive_remove_callback, 64, FTW_DEPTH | FTW_PHYS);
-}
-
-void exithandler(void)
-{
-	if(kv)
-		freekeyvalues(kv);
-	if (ifacefile)
-		fclose(ifacefile);
-}
-
-void usage(void)
-{
-#ifdef ovpndebug
-	printf("Wrapper for OpenVPN %s-debug\n", WRAPPERVERSION);
-#else
-	printf("Wrapper for OpenVPN %s\n", WRAPPERVERSION);
-#endif
-	printf("openvpnctrl <option>\n");
-	printf(" Valid options are:\n");
-	printf(" -s   --start\n");
-	printf("      starts OpenVPN (implicitly creates chains and firewall rules)\n");
-	printf(" -k   --kill\n");
-	printf("      kills/stops OpenVPN\n");
-	printf(" -r   --restart\n");
-	printf("      restarts OpenVPN (implicitly creates chains and firewall rules)\n");
-	printf(" -sn2n --start-net-2-net\n");
-	printf("      starts all net2net connections\n");
-	printf("      you may pass a connection name to the switch to only start a specific one\n");
-	printf(" -kn2n --kill-net-2-net\n");
-	printf("      kills all net2net connections\n");
-	printf("      you may pass a connection name to the switch to only start a specific one\n");
-	printf(" -drrd --delete-rrd\n");
-	printf("      Deletes the RRD data for a specific client\n");
-	printf("      you need to pass a connection name (RW) to the switch to delete the directory (case sensitive)\n");
-	printf(" -d   --display\n");
-	printf("      displays OpenVPN status to syslog\n");
-	printf(" -fwr --firewall-rules\n");
-	printf("      removes current OpenVPN chains and rules and resets them according to the config\n");
-	printf(" -sdo --start-daemon-only\n");
-	printf("      starts OpenVPN daemon only\n");
-	exit(1);
-}
-
-connection *getConnections() {
-	FILE *fp = NULL;
-
-	if (!(fp = fopen(CONFIG_ROOT "/ovpn/ovpnconfig", "r"))) {
-		fprintf(stderr, "Could not open openvpn n2n configuration file.\n");
-		exit(1);
-	}
-
-	char line[STRING_SIZE] = "";
-	char result[STRING_SIZE] = "";
-	char *resultptr;
-	int count;
-	connection *conn_first = NULL;
-	connection *conn_last = NULL;
-	connection *conn_curr;
-
-	while ((fgets(line, STRING_SIZE, fp) != NULL)) {
-		if (line[strlen(line) - 1] == '\n')
-			line[strlen(line) - 1] = '\0';
-
-		conn_curr = (connection *)malloc(sizeof(connection));
-		memset(conn_curr, 0, sizeof(connection));
-
-		if (conn_first == NULL) {
-			conn_first = conn_curr;
-		} else {
-			conn_last->next = conn_curr;
-		}
-		conn_last = conn_curr;
-
-		count = 0;
-		char *lineptr = line;
-		while (1) {
-			if (*lineptr == '\0')
-				break;
-
-			resultptr = result;
-			while (*lineptr != '\0') {
-				if (*lineptr == ',') {
-					lineptr++;
-					break;
-				}
-				*resultptr++ = *lineptr++;
-			}
-			*resultptr = '\0';
-
-			if (count == 1) {
-				strcpy(conn_curr->status, result);
-			} else if (count == 2) {
-				strcpy(conn_curr->name, result);
-			} else if (count == 4) {
-				strcpy(conn_curr->type, result);
-			} else if (count == 7) {
-				strcpy(conn_curr->role, result);
-			} else if (count == 9) {
-				strcpy(conn_curr->local_subnet, result);
-			} else if (count == 28) {
-				strcpy(conn_curr->transfer_subnet, result);
-			} else if (count == 29) {
-				strcpy(conn_curr->proto, result);
-			} else if (count == 30) {
-				strcpy(conn_curr->port, result);
-			}
-
-			count++;
-		}
-	}
-
-	fclose(fp);
-
-	return conn_first;
-}
-
-int readPidFile(const char *pidfile) {
-	FILE *fp = fopen(pidfile, "r");
-	if (fp == NULL) {
-		exit(1);
-	}
-
-	int pid = 0;
-	fscanf(fp, "%d", &pid);
-	fclose(fp);
-
-	return pid;
-}
-
-int readExternalAddress(char* address) {
-	FILE *fp = fopen("/var/ipfire/red/local-ipaddress", "r");
-	if (!fp)
-		goto ERROR;
-
-	int r = fscanf(fp, "%s", address);
-	fclose(fp);
-
-	if (r < 0)
-		goto ERROR;
-
-	/* In case the read IP address is not valid, we empty
-	 * the content of address and return non-zero. */
-	if (!VALID_IP(address))
-		goto ERROR;
-
-	return 0;
-
-ERROR:
-	address = NULL;
-	return 1;
-}
-
-void ovpnInit(void) {
-	// Read OpenVPN configuration
-	kv = initkeyvalues();
-	if (!readkeyvalues(kv, CONFIG_ROOT "/ovpn/settings")) {
-		fprintf(stderr, "Cannot read ovpn settings\n");
-		exit(1);
-	}
-
-	if (!findkey(kv, "ENABLED", enablered)) {
-		exit(1);
-	}
-
-	if (!findkey(kv, "ENABLED_BLUE", enableblue)){
-		exit(1);
-	}
-
-	if (!findkey(kv, "ENABLED_ORANGE", enableorange)){
-		exit(1);
-	}
-	freekeyvalues(kv);
-
-	// read interface settings
-
-	// details for the red int
-	memset(redif, 0, STRING_SIZE);
-	if ((ifacefile = fopen(CONFIG_ROOT "/red/iface", "r")))
-	{
-		if (fgets(redif, STRING_SIZE, ifacefile))
-		{
-			if (redif[strlen(redif) - 1] == '\n')
-				redif[strlen(redif) - 1] = '\0';
-		}
-		fclose (ifacefile);
-		ifacefile = NULL;
-
-		if (!VALID_DEVICE(redif))
-		{
-			memset(redif, 0, STRING_SIZE);
-		}
-	}
-
-	kv=initkeyvalues();
-	if (!readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")) {
-		fprintf(stderr, "Cannot read ethernet settings\n");
-		exit(1);
-	}
-
-	if (strcmp(enableblue, "on") == 0) {
-		if (!findkey(kv, "BLUE_DEV", blueif)) {
-			exit(1);
-		}
-	}
-
-	if (strcmp(enableorange, "on") == 0) {
-		if (!findkey(kv, "ORANGE_DEV", orangeif)) {
-			exit(1);
-		}
-	}
-	freekeyvalues(kv);
-}
-
-void executeCommand(char *command) {
-#ifdef ovpndebug
-	printf(strncat(command, "\n", 2));
-#endif
-	safe_system(strncat(command, " >/dev/null 2>&1", 17));
-}
-
-void addRule(const char *chain, const char *interface, const char *protocol, const char *port) {
-	char command[STRING_SIZE];
-
-	snprintf(command, STRING_SIZE - 1, "/sbin/iptables -A %s -i %s -p %s --dport %s -j ACCEPT",
-		chain, interface, protocol, port);
-	executeCommand(command);
-}
-
-void flushChain(char *chain) {
-	char str[STRING_SIZE];
-
-	snprintf(str, STRING_SIZE - 1, "/sbin/iptables -F %s", chain);
-	executeCommand(str);
-}
-
-void flushChainNAT(char *chain) {
-	char str[STRING_SIZE];
-
-	snprintf(str, STRING_SIZE - 1, "/sbin/iptables -t nat -F %s", chain);
-	executeCommand(str);
-}
-
-char* calcTransferNetAddress(const connection* conn) {
-	char *subnetmask = strdup(conn->transfer_subnet);
-	char *address = strsep(&subnetmask, "/");
-
-	if ((address == NULL) || (subnetmask == NULL)) {
-		goto ERROR;
-	}
-
-	in_addr_t _address    = inet_addr(address);
-	in_addr_t _subnetmask = inet_addr(subnetmask);
-	_address &= _subnetmask;
-
-	if (strcmp(conn->role, "server") == 0) {
-		_address += 1 << 24;
-	} else if (strcmp(conn->role, "client") == 0) {
-		_address += 2 << 24;
-	} else {
-		goto ERROR;
-	}
-
-	struct in_addr address_info;
-	address_info.s_addr = _address;
-
-	return inet_ntoa(address_info);
-
-ERROR:
-	fprintf(stderr, "Could not determine transfer net address: %s\n", conn->name);
-
-	free(address);
-	return NULL;
-}
-
-char* getLocalSubnetAddress(const connection* conn) {
-	kv = initkeyvalues();
-	if (!readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")) {
-		fprintf(stderr, "Cannot read ethernet settings\n");
-		exit(1);
-	}
-
-	const char *zones[] = {"GREEN", "BLUE", "ORANGE", NULL};
-	const char *zone = NULL;
-
-	// Get net address of the local openvpn subnet.
-	char *subnetmask = strdup(conn->local_subnet);
-	char *address = strsep(&subnetmask, "/");
-
-	if ((address == NULL) || (subnetmask == NULL)) {
-		goto ERROR;
-	}
-
-	in_addr_t _address    = inet_addr(address);
-	in_addr_t _subnetmask = inet_addr(subnetmask);
-
-	in_addr_t _netaddr    = (_address &  _subnetmask);
-	in_addr_t _broadcast  = (_address | ~_subnetmask);
-
-	char zone_address_key[STRING_SIZE];
-	char zone_address[STRING_SIZE];
-	in_addr_t zone_addr;
-
-	int i = 0;
-	while (zones[i]) {
-		zone = zones[i++];
-		snprintf(zone_address_key, STRING_SIZE, "%s_ADDRESS", zone);
-
-		if (!findkey(kv, zone_address_key, zone_address))
-			continue;
-
-		zone_addr = inet_addr(zone_address);
-		if ((zone_addr > _netaddr) && (zone_addr < _broadcast)) {
-			freekeyvalues(kv);
 
-			return strdup(zone_address);
-		}
-	}
-
-ERROR:
-	fprintf(stderr, "Could not determine local subnet address: %s\n", conn->name);
-
-	freekeyvalues(kv);
-	return NULL;
-}
-
-void setFirewallRules(void) {
-	char command[STRING_SIZE];
-	char protocol[STRING_SIZE] = "";
-	char dport[STRING_SIZE] = "";
-	char dovpnip[STRING_SIZE] = "";
+#include "setuid.h"
 
-	kv = initkeyvalues();
-	if (!readkeyvalues(kv, CONFIG_ROOT "/ovpn/settings"))
-	{
-		fprintf(stderr, "Cannot read ovpn settings\n");
-		exit(1);
-	}
+int main(int argc, char** argv) {
+	const char* command = NULL;
 
-	/* we got one device, so lets proceed further	*/
-	if (!findkey(kv, "DDEST_PORT", dport)){
-		fprintf(stderr, "Cannot read DDEST_PORT\n");
+	// Become root
+	if (!initsetuid())
 		exit(1);
-	}
 
-	if (!findkey(kv, "DPROTOCOL", protocol)){
-		fprintf(stderr, "Cannot read DPROTOCOL\n");
+	// Check if we have enough arguments
+	if (argc < 2) {
+		fprintf(stderr, "\nNot enough arguments.\n\n");
 		exit(1);
 	}
 
-	if (!findkey(kv, "VPN_IP", dovpnip)){
-		fprintf(stderr, "Cannot read VPN_IP\n");
-	}
-	freekeyvalues(kv);
-
-	// Flush all chains.
-	flushChain(OVPNINPUT);
-	flushChain(OVPNBLOCK);
-	flushChainNAT(OVPNNAT);
-
-	// set firewall rules
-	if (!strcmp(enablered, "on") && strlen(redif))
-		addRule(OVPNINPUT, redif, protocol, dport);
-	if (!strcmp(enableblue, "on") && strlen(blueif))
-		addRule(OVPNINPUT, blueif, protocol, dport);
-	if (!strcmp(enableorange, "on") && strlen(orangeif))
-		addRule(OVPNINPUT, orangeif, protocol, dport);
-
-	/* Allow ICMP error messages to pass. */
-	snprintf(command, STRING_SIZE - 1, "/sbin/iptables -A %s -p icmp"
-		" -m conntrack --ctstate RELATED -j RETURN", OVPNBLOCK);
-	executeCommand(command);
-
-	// read connection configuration
-	connection *conn = getConnections();
+	// Roadwarrior
+	if (strcmp(argv[1], "rw") == 0) {
+		command = "/etc/rc.d/init.d/openvpn-rw";
 
-	// set firewall rules for n2n connections
-	char *local_subnet_address = NULL;
-	char *transfer_subnet_address = NULL;
-	while (conn != NULL) {
-		if (strcmp(conn->type, "net") == 0) {
-			addRule(OVPNINPUT, redif, conn->proto, conn->port);
+	// N2N
+	} else if (strcmp(argv[1], "n2n") == 0) {
+		command = "/etc/rc.d/init.d/openvpn-n2n";
 
-			/* Block all communication from the transfer nets. */
-			snprintf(command, STRING_SIZE - 1, "/sbin/iptables -A %s -s %s -j DROP",
-				OVPNBLOCK, conn->transfer_subnet);
-			executeCommand(command);
-
-			local_subnet_address = getLocalSubnetAddress(conn);
-			transfer_subnet_address = calcTransferNetAddress(conn);
-
-			if ((local_subnet_address) && (transfer_subnet_address)) {
-				snprintf(command, STRING_SIZE - 1, "/sbin/iptables -t nat -A %s -s %s -j SNAT --to-source %s",
-					OVPNNAT, transfer_subnet_address, local_subnet_address);
-				executeCommand(command);
-			}
-		}
-
-		conn = conn->next;
-	}
-}
-
-static void stopAuthenticator() {
-	char* argv[] = {
-		"/usr/sbin/openvpn-authenticator",
-		NULL,
-	};
-
-	run("/bin/killall", argv);
-}
-
-void stopDaemon(void) {
-	char command[STRING_SIZE];
-
-	// Stop OpenVPN authenticator
-	stopAuthenticator();
-
-	int pid = readPidFile("/var/run/openvpn.pid");
-	if (pid <= 0) {
-		exit(1);
-	}
-
-	fprintf(stderr, "Killing PID %d.\n", pid);
-	kill(pid, SIGTERM);
-
-	snprintf(command, STRING_SIZE - 1, "/bin/rm -f /var/run/openvpn.pid");
-	executeCommand(command);
-}
-
-static int startAuthenticator(void) {
-	char* argv[] = { "-d", NULL };
-
-	return run("/usr/sbin/openvpn-authenticator", argv);
-}
-
-void startDaemon(void) {
-	char command[STRING_SIZE];
-
-	if (!((strcmp(enablered, "on") == 0) || (strcmp(enableblue, "on") == 0) || (strcmp(enableorange, "on") == 0))) {
-		fprintf(stderr, "OpenVPN is not enabled on any interface\n");
-		exit(1);
+	// Unknown
 	} else {
-		snprintf(command, STRING_SIZE-1, "/etc/fcron.daily/openvpn-crl-updater");
-		executeCommand(command);
-		snprintf(command, STRING_SIZE-1, "/sbin/modprobe tun");
-		executeCommand(command);
-		snprintf(command, STRING_SIZE-1, "/usr/sbin/openvpn --config /var/ipfire/ovpn/server.conf");
-		executeCommand(command);
-		snprintf(command, STRING_SIZE-1, "/bin/chown root:nobody /var/run/ovpnserver.log");
-		executeCommand(command);
-		snprintf(command, STRING_SIZE-1, "/bin/chmod 644 /var/run/ovpnserver.log");
-		executeCommand(command);
-
-		// Start OpenVPN Authenticator
-		startAuthenticator();
-	}
-}
-
-int startNet2Net(char *name) {
-	connection *conn = NULL;
-	connection *conn_iter;
-
-	conn_iter = getConnections();
-
-	while (conn_iter) {
-		if ((strcmp(conn_iter->type, "net") == 0) && (strcmp(conn_iter->name, name) == 0)) {
-			conn = conn_iter;
-			break;
-		}
-		conn_iter = conn_iter->next;
-	}
-
-	if (conn == NULL) {
-		fprintf(stderr, "Connection not found.\n");
-		return 1;
-	}
-
-	if (strcmp(conn->status, "on") != 0) {
-		fprintf(stderr, "Connection '%s' is not enabled.\n", conn->name);
-		return 1;
-	}
-
-	fprintf(stderr, "Starting connection %s...\n", conn->name);
-
-	char configfile[STRING_SIZE];
-	snprintf(configfile, STRING_SIZE - 1, CONFIG_ROOT "/ovpn/n2nconf/%s/%s.conf",
-		conn->name, conn->name);
-
-	FILE *fp = fopen(configfile, "r");
-	if (fp == NULL) {
-		fprintf(stderr, "Could not find configuration file for connection '%s' at '%s'.\n",
-			conn->name, configfile);
-		return 2;
-	}
-	fclose(fp);
-
-	// Make sure all firewall rules are up to date.
-	setFirewallRules();
-
-	// Get the external IP address.
-	char address[STRING_SIZE] = "";
-	int r = readExternalAddress(address);
-	if (r) {
-		fprintf(stderr, "Could not read the external address\n");
+		fprintf(stderr, "Invalid connection type '%s'\n", argv[1]);
 		exit(1);
 	}
 
-	char command[STRING_SIZE];
-	snprintf(command, STRING_SIZE-1, "/sbin/modprobe tun");
-	executeCommand(command);
-	snprintf(command, STRING_SIZE-1, "/usr/sbin/openvpn --local %s --config %s", address, configfile);
-	executeCommand(command);
-
-	return 0;
-}
-
-int killNet2Net(char *name) {
-	connection *conn = NULL;
-	connection *conn_iter;
-	int rc = 0;
-
-	conn_iter = getConnections();
-
-	while (conn_iter) {
-		if (strcmp(conn_iter->name, name) == 0) {
-			conn = conn_iter;
-			break;
-		}
-		conn_iter = conn_iter->next;
-	}
-
-	if (conn == NULL) {
-		fprintf(stderr, "Connection not found.\n");
-		return 1;
-	}
-
-	char pidfile[STRING_SIZE];
-	snprintf(pidfile, STRING_SIZE - 1, "/var/run/%sn2n.pid", conn->name);
-
-	int pid = readPidFile(pidfile);
-	if (pid <= 0) {
-		fprintf(stderr, "Could not read pid file of connection %s.", conn->name);
-		return 1;
-	}
-
-	fprintf(stderr, "Killing connection %s (PID %d)...\n", conn->name, pid);
-	kill(pid, SIGTERM);
-
-	char command[STRING_SIZE];
-	snprintf(command, STRING_SIZE - 1, "/bin/rm -f %s", pidfile);
-	executeCommand(command);
-
-	char runfile[STRING_SIZE];
-	snprintf(runfile, STRING_SIZE - 1, "/var/run/openvpn/%s-n2n", conn->name);
-	rc = recursive_remove(runfile);
-	if (rc)
-		perror(runfile);
-
-	return 0;
-}
-
-int deleterrd(char *name) {
-	char rrd_dir[STRING_SIZE];
-
-	connection *conn = getConnections();
-	while(conn) {
-		if (strcmp(conn->name, name) != 0) {
-			conn = conn->next;
-			continue;
-		}
-
-		// Handle RW connections
-		if (strcmp(conn->type, "host") == 0) {
-			snprintf(rrd_dir, STRING_SIZE - 1, "/var/log/rrd/collectd/localhost/openvpn-%s/", name);
-
-		// Handle N2N connections
-		} else if (strcmp(conn->type, "net") == 0) {
-			snprintf(rrd_dir, STRING_SIZE - 1, "/var/log/rrd/collectd/localhost/openvpn-%s-n2n/", name);
-
-		// Unhandled connection type
-		} else {
-			conn = conn->next;
-			continue;
-		}
-
-		return recursive_remove(rrd_dir);
-	}
-
-	return 1;
-}
-
-void startAllNet2Net() {
-	int exitcode = 0, _exitcode = 0;
-
-	connection *conn = getConnections();
-
-	while(conn) {
-		/* Skip all connections that are not of type "net" or disabled. */
-		if ((strcmp(conn->type, "net") != 0) || (strcmp(conn->status, "on") != 0)) {
-			conn = conn->next;
-			continue;
-		}
-
-		_exitcode = startNet2Net(conn->name);
-		conn = conn->next;
-
-		if (_exitcode > exitcode) {
-			exitcode = _exitcode;
-		}
-	}
-
-	exit(exitcode);
-}
-
-void killAllNet2Net() {
-	int exitcode = 0, _exitcode = 0;
-
-	connection *conn = getConnections();
-
-	while(conn) {
-		/* Skip all connections that are not of type "net". */
-		if (strcmp(conn->type, "net") != 0) {
-			conn = conn->next;
-			continue;
-		}
-
-		_exitcode = killNet2Net(conn->name);
-		conn = conn->next;
-
-		if (_exitcode > exitcode) {
-			exitcode = _exitcode;
-		}
-	}
-
-	exit(exitcode);
-}
-
-void displayopenvpn(void) {
-	char command[STRING_SIZE];
-
-	snprintf(command, STRING_SIZE - 1, "/bin/killall -sSIGUSR2 openvpn");
-	executeCommand(command);
+	return run(command, argv + 2);
 }
-
-int main(int argc, char *argv[]) {
-	if (!(initsetuid()))
-	    exit(1);
-	if(argc < 2)
-	    usage();
-
-	if(argc == 3) {
-		ovpnInit();
-
-		if( (strcmp(argv[1], "-sn2n") == 0) || (strcmp(argv[1], "--start-net-2-net") == 0) ) {
-			startNet2Net(argv[2]);
-			return 0;
-		}
-		else if( (strcmp(argv[1], "-kn2n") == 0) || (strcmp(argv[1], "--kill-net-2-net") == 0) ) {
-			killNet2Net(argv[2]);
-			return 0;
-		}
-		else if( (strcmp(argv[1], "-drrd") == 0) || (strcmp(argv[1], "--delete-rrd") == 0) ) {
-			deleterrd(argv[2]);
-			return 0;
-		} else {
-			usage();
-			return 1;
-		}
-	}
-	else if(argc == 2) {
-		if( (strcmp(argv[1], "-k") == 0) || (strcmp(argv[1], "--kill") == 0) ) {
-			stopDaemon();
-			return 0;
-		}
-		else if( (strcmp(argv[1], "-d") == 0) || (strcmp(argv[1], "--display") == 0) ) {
-			displayopenvpn();
-			return 0;
-		}
-		else {
-			ovpnInit();
-
-			if( (strcmp(argv[1], "-s") == 0) || (strcmp(argv[1], "--start") == 0) ) {
-				setFirewallRules();
-				startDaemon();
-				return 0;
-			}
-			else if( (strcmp(argv[1], "-sn2n") == 0) || (strcmp(argv[1], "--start-net-2-net") == 0) ) {
-				startAllNet2Net();
-				return 0;
-			}
-			else if( (strcmp(argv[1], "-kn2n") == 0) || (strcmp(argv[1], "--kill-net-2-net") == 0) ) {
-				killAllNet2Net();
-				return 0;
-			}
-			else if( (strcmp(argv[1], "-sdo") == 0) || (strcmp(argv[1], "--start-daemon-only") == 0) ) {
-				startDaemon();
-				return 0;
-			}
-			else if( (strcmp(argv[1], "-r") == 0) || (strcmp(argv[1], "--restart") == 0) ) {
-				stopDaemon();
-				setFirewallRules();
-				startDaemon();
-				return 0;
-			}
-			else if( (strcmp(argv[1], "-fwr") == 0) || (strcmp(argv[1], "--firewall-rules") == 0) ) {
-				setFirewallRules();
-				return 0;
-			}
-			else {
-				usage();
-				return 0;
-			}
-		}
-	}
-	else {
-		usage();
-		return 0;
-	}
-return 0;
-}
-


hooks/post-receive
--
IPFire 2.x development tree


                 reply	other threads:[~2025-07-15  9:57 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4bhF3c51DCz2xfL@people01.haj.ipfire.org \
    --to=git@ipfire.org \
    --cc=ipfire-scm@lists.ipfire.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox