Advertisement
Guest User

Untitled

a guest
Feb 26th, 2016
220
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.06 KB | None | 0 0
  1. #!/usr/local/bin/php -f
  2. <?php
  3.  
  4. # PROVIDE: ec2_setup
  5. # REQUIRE: NETWORKING
  6. # BEFORE: LOGIN
  7.  
  8. require("globals.inc");
  9. require("config.inc");
  10. require("auth.inc");
  11. require("interfaces.inc");
  12. require("certs.inc");
  13. require("openvpn.inc");
  14.  
  15. function retrieveMetaData($url) {
  16.  
  17. if (!$url)
  18. return;
  19.  
  20. $curl = curl_init();
  21. curl_setopt($curl, CURLOPT_URL, $url);
  22. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  23. curl_setopt($curl, CURLOPT_FAILONERROR, true);
  24. curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 15);
  25. curl_setopt($curl, CURLOPT_TIMEOUT, 30);
  26. $metadata = curl_exec($curl);
  27. curl_close($curl);
  28.  
  29. return($metadata);
  30. }
  31.  
  32.  
  33. function retrieveSSHKey() {
  34.  
  35. $url = "http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key";
  36. return(retrieveMetaData($url));
  37. }
  38.  
  39. function retrieveUserData() {
  40.  
  41. $url = "http://169.254.169.254/latest/user-data/";
  42. $user_data = retrieveMetaData($url);
  43.  
  44. if (!$user_data)
  45. return;
  46.  
  47. /* userdata is formatted like this:
  48. foo1=bar1:foo2=bar2:...:fooN=barN
  49. what, were you raised in a barN? */
  50.  
  51. $kv_pairs = explode(':', $user_data);
  52. foreach ($kv_pairs as $pair) {
  53. list($key, $value) = explode("=", $pair, 2);
  54. $ud[$key] = $value;
  55. }
  56.  
  57. return($ud);
  58.  
  59. }
  60.  
  61. function retrievePublicIP() {
  62.  
  63. $wanintf = get_real_wan_interface();
  64. $macaddr = get_interface_mac($wanintf);
  65. if (!$macaddr)
  66. return;
  67.  
  68. $url = "http://169.254.169.254/latest/meta-data/network/interfaces/macs/$macaddr/public-ipv4s";
  69. $public_ipv4 = retrieveMetaData($url);
  70.  
  71. if (is_ipaddrv4($public_ipv4)) {
  72. $natipfile = "/var/db/natted_{$wanintf}_ip";
  73. file_put_contents($natipfile, $public_ipv4);
  74. return($public_ipv4);
  75. }
  76.  
  77. return;
  78. }
  79.  
  80. function generateRandomPassword($length = 15) {
  81.  
  82. /* get some random bytes. use them as offsets into the space of
  83. printable ascii characters. 32-126 is the printable characters.
  84. Omit 32 itself since it might be confusing if there is a space
  85. in the password.
  86. */
  87.  
  88. $range_size = 126 - 33 + 1;
  89. $random_bytes = str_split(openssl_random_pseudo_bytes($length));
  90.  
  91. for ($i = 0; $i < $length; $i++) {
  92.  
  93. $offset = ord($random_bytes[$i]) % $range_size;
  94. $password .= chr(33 + $offset);
  95.  
  96. }
  97.  
  98. return $password;
  99. }
  100.  
  101. function addCA() {
  102.  
  103. global $config;
  104. if (!is_array($config['ca']))
  105. $config['ca'] = array();
  106.  
  107. $a_ca = &$config['ca'];
  108.  
  109. $ca_cfg['keylen'] = 2048;
  110. $ca_cfg['digest_alg'] = 'sha256';
  111. $ca_cfg['lifetime'] = 3650;
  112.  
  113. $dn['countryName'] = 'US';
  114. $dn['stateOrProvinceName'] = 'TX';
  115. $dn['localityName'] = 'Austin';
  116. $dn['organizationName'] = 'Netgate VPN';
  117. $dn['emailAddress'] = 'email';
  118. $dn['commonName'] = 'Netgate VPN CA';
  119.  
  120. $ca = array();
  121. $ca['refid'] = uniqid();
  122. $ca['descr'] = 'Netgate Auto VPN CA';
  123.  
  124. if (!ca_create($ca, $ca_cfg['keylen'], $ca_cfg['lifetime'], $dn, $ca_cfg['digest_alg'])) {
  125. $ssl_errs = 0;
  126. while ($ssl_err = openssl_error_string()) {
  127. $ssl_errs++;
  128. $last_ssl_err = $ssl_err;
  129. }
  130. if ($ssl_errs) {
  131. echo "Errors creating CA cert: $last_ssl_err\n";
  132. return;
  133. }
  134. }
  135.  
  136. $a_ca[] = $ca;
  137. return($ca['refid']);
  138. }
  139.  
  140. function addServerCert($caref) {
  141.  
  142. global $config;
  143.  
  144. if (!is_array($config['cert']))
  145. $config['cert'] = array();
  146.  
  147. $a_cert = &$config['cert'];
  148.  
  149. $cert_cfg['keylen'] = 2048;
  150. $cert_cfg['csr_keylen'] = 2048;
  151. $cert_cfg['digest_alg'] = 'sha256';
  152. $cert_cfg['type'] = 'server';
  153. $cert_cfg['lifetime'] = 3650;
  154.  
  155. $dn['countryName'] = 'US';
  156. $dn['stateOrProvinceName'] = 'TX';
  157. $dn['localityName'] = 'Austin';
  158. $dn['organizationName'] = 'Netgate VPN';
  159. $dn['emailAddress'] = 'email';
  160. $dn['commonName'] = 'Netgate VPN Server';
  161.  
  162. $cert = array();
  163. $cert['refid'] = uniqid();
  164. $cert['descr'] = 'Netgate Auto VPN Server Cert';
  165.  
  166. if (!cert_create($cert, $caref, $cert_cfg['keylen'],
  167. $cert_cfg['lifetime'], $dn, $cert_cfg['type'], $cert_cfg['digest_alg'])) {
  168. $ssl_errs = 0;
  169. while ($ssl_err = openssl_error_string()) {
  170. $ssl_errs++;
  171. $last_ssl_err = $ssl_err;
  172. }
  173. if ($ssl_errs) {
  174. echo "Errors creating cert: $last_ssl_err\n";
  175. return;
  176. }
  177. }
  178.  
  179. $a_cert[] = $cert;
  180. return($cert['refid']);
  181. }
  182.  
  183. function addOpenVPNServer() {
  184.  
  185. global $config;
  186.  
  187. if (!is_array($config['openvpn']['openvpn-server']))
  188. $config['openvpn']['openvpn-server'] = array();
  189.  
  190. $a_server = &$config['openvpn']['openvpn-server'];
  191.  
  192. /* don't do anything if it's previously been done */
  193. if (isset($a_server[0]['description']) &&
  194. ($a_server[0]['description'] == 'Netgate Auto Remote Access VPN'))
  195. return;
  196.  
  197. $server['vpnid'] = 0;
  198. $server['disable'] = '';
  199. $server['mode'] = 'server_user';
  200. $server['authmode'] = 'Local Database';
  201. $server['protocol'] = 'UDP';
  202. $server['dev_mode'] = 'tun';
  203. $server['interface'] = 'wan';
  204. $server['local_port'] = 1194;
  205. $server['description'] = 'Netgate Auto Remote Access VPN';
  206. $server['tlsauth_enable'] = 'no';
  207. $server['autotls_enable'] = 'no';
  208. $server['caref'] = addCA();
  209. if (!isset($server['caref']))
  210. return;
  211. $server['certref'] = addServerCert($server['caref']);
  212. if (!isset($server['certref']))
  213. return;
  214. $server['dh_length'] = 1024;
  215. $server['crypto'] = 'AES-128-CBC';
  216. $server['engine'] = 'none';
  217. $server['cert_depth'] = 1;
  218. $server['tunnel_network'] = '172.24.42.0/24';
  219. $server['gwredir'] = 'yes';
  220. $server['compression'] = 'yes';
  221. $server['duplicate_cn'] = true;
  222. $server['topology_subnet'] = 'yes';
  223. $server['custom_options'] = 'push "route-ipv6 0::0/1 vpn_gateway";push "route-ipv6 8000::0/1 vpn_gateway";';
  224. $server['tunnel_networkv6'] = 'fd6f:826b:ed1e::0/64';
  225. $server['dns_server_enable'] = true;
  226. $server['dns_server1'] = '172.24.42.1';
  227.  
  228. $a_server[] = $server;
  229.  
  230. openvpn_resync('server', $server);
  231. return;
  232. }
  233.  
  234. function configureMgmtNetRules($mgmtnet) {
  235.  
  236. global $config;
  237.  
  238. /*
  239. Since the EC2 VM must be managed over the internet, access to SSH
  240. & web is open to the outside. By default it is open to anywhere
  241. because it is unknown at image creation time where the user will be
  242. coming from. User can pass in a management network to allow in
  243. the user data field that will be used to replace 'any' in the
  244. default filter rules.
  245.  
  246. find rules with '_replace_src_with_mgmtnet_' in the description and
  247. replace the source network with $mgmtnet
  248.  
  249. could also add a tag to look for that indicates the destination
  250. address (or other attributes) should be substituted
  251. */
  252.  
  253. $src_addr_tag = '_replace_src_with_mgmtnet_';
  254.  
  255. if (! (is_ipaddrv4($mgmtnet) || is_subnetv4($mgmtnet)) ) {
  256. echo "Invalid management subnet/address: $mgmtnet\n";
  257. return;
  258. }
  259.  
  260. if (!is_array($config['filter']['rule']))
  261. $config['filter']['rule'] = array();
  262. $a_filter = &$config['filter']['rule'];
  263.  
  264. foreach ($a_filter as &$rule) {
  265. $pos = strpos($rule['descr'], $src_addr_tag);
  266. if ($pos !== false) {
  267. unset($rule['source']['any']);
  268. $rule['source']['address'] = $mgmtnet;
  269. $rule['descr'] = str_replace($src_addr_tag, "", $rule['descr']);
  270. }
  271. }
  272.  
  273. return(true);
  274. }
  275.  
  276. function writeOpenVPNConfig($publicIP) {
  277.  
  278. global $config;
  279.  
  280. /* check if the first openvpn server is the automatically generated
  281. remote access VPN server before writing the config */
  282. if (!is_array($config['openvpn']['openvpn-server']) ||
  283. !isset($config['openvpn']['openvpn-server'][0]['description']) ||
  284. ($config['openvpn']['openvpn-server'][0]['description'] !=
  285. 'Netgate Auto Remote Access VPN'))
  286. return;
  287.  
  288. $cfgDir = "/usr/local/libdata/vpn-profile";
  289. $ovpnCfgFile = "remote-access-openvpn.ovpn";
  290. $cfgTemplateDir = "/usr/local/libdata/html-template";
  291.  
  292. if (!file_exists($cfgDir))
  293. mkdir($cfgDir, 0755, true);
  294.  
  295. /* read the template file and replace the placeholders */
  296. $newOvpnCfg = file_get_contents("$cfgTemplateDir/$ovpnCfgFile");
  297. if (!isset($newOvpnCfg))
  298. return;
  299.  
  300. $newOvpnCfg = str_replace('__PUBLIC_IP__', $publicIP, $newOvpnCfg);
  301. $ca = $config['ca'][0]['crt'];
  302. if ($ca) {
  303. $newOvpnCfg = str_replace('__CA_CRT__', base64_decode($ca), $newOvpnCfg);
  304. }
  305.  
  306. /* do not write a file if one of the fields was missing */
  307. if (!($publicIP && $ca))
  308. return;
  309.  
  310. if (!file_exists("$cfgDir/$ovpnCfgFile") ||
  311. (file_get_contents("$cfgDir/$ovpnCfgFile") !== $newOvpnCfg))
  312. file_put_contents("$cfgDir/$ovpnCfgFile", $newOvpnCfg);
  313.  
  314. return;
  315. }
  316.  
  317.  
  318. function initialSystemConfig() {
  319.  
  320. global $config;
  321.  
  322. /* admin user should exist already, exit if it doesnt */
  323. if (!(is_array($config['system']['user']) && isset($config['system']['user'][0]))) {
  324. echo "Didn't find user data in config. Exiting EC2 setup.\n";
  325. exit;
  326. }
  327. $admin_user = &$config['system']['user'][0];
  328.  
  329. /* get the administative SSH Key and add it to the config */
  330. if (!isset($admin_user['authorizedkeys'])) {
  331. $ssh_key = retrieveSSHKey();
  332. if ($ssh_key) {
  333. echo "SSH Key retrieved: $ssh_key\n";
  334. $admin_user['authorizedkeys'] = base64_encode($ssh_key);
  335. } else
  336. echo "Failed to retrieve an SSH key for administrative access\n";
  337. }
  338.  
  339. /* get user metadata, set admin password if one was specified */
  340. $user_data = retrieveUserData();
  341. if ($user_data && isset($user_data['password']))
  342. $admin_password = $user_data['password'];
  343. else
  344. /* none specified, generate a random one */
  345. $admin_password = generateRandomPassword();
  346.  
  347. if ($admin_password) {
  348. $pw_string = "***\n***\n";
  349. $pw_string .= "*** Admin password changed to: $admin_password\n";
  350. $pw_string .= "***\n***\n";
  351. local_user_set_password($admin_user, $admin_password);
  352. file_put_contents("/etc/motd", $pw_string);
  353. unlink("/root/.hushlogin");
  354. } else
  355. echo "No password generated for admin, keeping default password\n";
  356. local_user_set($admin_user);
  357.  
  358. /* add a disabled remote access OpenVPN server */
  359. addOpenVPNServer();
  360.  
  361. if (isset($user_data['mgmtnet']))
  362. configureMgmtNetRules($user_data['mgmtnet']);
  363.  
  364. unset($config['system']['doinitialsetup']);
  365. write_config();
  366. }
  367.  
  368. if ($argv[1] == 'start') {
  369. if (isset($config['system']['doinitialsetup']))
  370. initialSystemConfig();
  371. $publicIP = retrievePublicIP();
  372. writeOpenVPNConfig($publicIP);
  373. }
  374.  
  375. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement