├── VERSION ├── 404.php ├── .gitattributes ├── README.md ├── .gitignore ├── config.dist.php ├── .htaccess ├── functions.php ├── stylesheet.css ├── api.php └── index.php /VERSION: -------------------------------------------------------------------------------- 1 | 10 -------------------------------------------------------------------------------- /404.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GeoIP_Server 2 | Simple php geoip server that returns map and json (uses MaxMind data) 3 | 4 | Automate installation and updating MaxMind data: https://github.com/palinkas-jo-reggelt/GeoLite2SQL 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore config file & testing files 2 | /config.php 3 | /test* 4 | 5 | # Ignoring directories 6 | # Both the directory itself and its contents will be ignored. 7 | uploads/ 8 | photos/ 9 | tmp/ 10 | giveout/ -------------------------------------------------------------------------------- /config.dist.php: -------------------------------------------------------------------------------- 1 | 'localhost', 9 | 'username' => 'geoip', 10 | 'password' => 'supersecretpassword', 11 | 'dbname' => 'geoip', 12 | 'table_city' => 'geocity', // table name for city ip data 13 | 'table_loc' => 'citylocations', // table name for city location name data 14 | 'driver' => 'mysql', 15 | 'port' => '3306' 16 | ); 17 | 18 | ?> -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | RewriteEngine On 2 | RewriteRule ^api$ /api.php [NC,L] 3 | RewriteRule ^api/$ /api.php [NC,L] 4 | RewriteRule ^api/(.*)$ /api.php?geoip=$1 [NC,L] 5 | RewriteRule ^map/(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3})|((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))))$ /index.php?geoip=$1 [NC,L] 6 | RewriteRule ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3})$ /index.php?geoip=$1 [NC,L] 7 | ErrorDocument 404 /404.php 8 | -------------------------------------------------------------------------------- /functions.php: -------------------------------------------------------------------------------- 1 | = ip2long('100.64.0.0')) && (ip2long($geoip) <= ip2long('100.127.255.255'))) {return true;} 12 | else if ((ip2long($geoip) >= ip2long('172.16.0.0')) && (ip2long($geoip) <= ip2long('172.31.255.255'))) {return true;} 13 | else if ((ip2long($geoip) >= ip2long('224.0.0.0')) && (ip2long($geoip) <= ip2long('239.255.255.255'))) {return true;} 14 | else if ((ip2long($geoip) >= ip2long('240.0.0.0')) && (ip2long($geoip) <= ip2long('255.255.255.255'))) {return true;} 15 | else {return false;} 16 | } 17 | 18 | ?> -------------------------------------------------------------------------------- /stylesheet.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #fefefe; 3 | font-family: "Roboto"; 4 | font-size: 12pt; 5 | } 6 | 7 | a:link, a:active, a:visited { 8 | color: #FF0000; 9 | text-transform: underline; 10 | } 11 | 12 | a:hover { 13 | color: #FF0000; 14 | text-transform: none; 15 | } 16 | 17 | .wrapper { 18 | max-width: 900px; 19 | position: relative; 20 | margin: auto; 21 | /* padding-top: 10px; */ 22 | } 23 | 24 | .section { 25 | padding: 5px 0 15px 0; 26 | /* margin: 10px; */ 27 | display: block; 28 | /* border: 1px dashed #ccc; */ 29 | /* border-radius: 20px; */ 30 | } 31 | 32 | .section a:link, a:visited { 33 | color: black; 34 | text-decoration: none; 35 | } 36 | 37 | .section a:hover, a:active { 38 | color: red; 39 | text-decoration: underline; 40 | } 41 | 42 | .section h2 { 43 | font-size:16px; 44 | font-weight:bold; 45 | text-align:left; 46 | } 47 | 48 | .section h3 { 49 | font-size:25px; 50 | font-weight:bold; 51 | text-align:center; 52 | } 53 | 54 | .secleft { 55 | float: left; 56 | width: 50%; 57 | display: block; 58 | } 59 | 60 | .secright { 61 | float: right; 62 | width: 50%; 63 | display: block; 64 | } 65 | 66 | .secinner{ 67 | box-sizing: border-box; 68 | padding: 0 5px 5px 5px; 69 | } 70 | 71 | #map { 72 | max-width: 450px; 73 | width: calc(100vw-10px); 74 | height: 50vh; 75 | } 76 | 77 | .footer { 78 | line-height: 1.5em; 79 | text-align: center; 80 | font-size: 0.6em; 81 | } 82 | 83 | .clear { 84 | clear: both; 85 | } 86 | 87 | /* ### SIMPLE TABLE CSS ### */ 88 | .simple-div-table { 89 | display: table; 90 | width: 100%; 91 | font-size: 0.8em; 92 | border-left: 1px solid #ccc; 93 | border-bottom: 1px solid #ccc; 94 | } 95 | 96 | .simple-div-table-row-header { 97 | display: table-row; 98 | font-weight: bold; 99 | text-align: center; 100 | background: yellow; 101 | } 102 | 103 | .simple-div-table-row { 104 | display: table-row; 105 | } 106 | 107 | .simple-div-table-row:nth-of-type(even) { 108 | background: #eee; 109 | border: 1px solid #ccc; 110 | } 111 | 112 | .simple-div-table-col { 113 | display: table-cell; 114 | padding: 3px; 115 | border-right: 1px solid #ccc; 116 | border-top: 1px solid #ccc; 117 | } 118 | 119 | .center { 120 | text-align: center; 121 | } 122 | 123 | .right { 124 | text-align: right; 125 | } 126 | 127 | .left { 128 | text-align: left; 129 | } 130 | 131 | @media only screen and (max-width: 380px) { 132 | .wrapper { 133 | /* width: 345px; */ 134 | } 135 | .secleft { 136 | float: none; 137 | width: 100%; 138 | } 139 | .secright { 140 | float: none; 141 | margin: 0px; 142 | width: 100% ; 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /api.php: -------------------------------------------------------------------------------- 1 | prepare(" 18 | SELECT * 19 | FROM ( 20 | SELECT * 21 | FROM ".$Database['table_city']." 22 | WHERE INET6_ATON('".$geoip."') <= network_end LIMIT 1 23 | ) AS a 24 | INNER JOIN ".$Database['table_loc']." AS b ON a.geoname_id = b.geoname_id 25 | WHERE network_start <= INET6_ATON('".$geoip."'); 26 | "); 27 | $sql->execute(); 28 | while($row = $sql->fetch(PDO::FETCH_ASSOC)){ 29 | $json = array( 30 | 'status'=>200, 31 | 'message'=>'IP Found', 32 | 'data'=>array( 33 | 'reserved_ip'=>false, 34 | 'ip'=>$geoip, 35 | 'postal_code'=>$row["postal_code"], 36 | 'latitude'=>$row["latitude"], 37 | 'longitude'=>$row["longitude"], 38 | 'accuracy_radius'=>$row["accuracy_radius"], 39 | 'locale_code'=>$row["locale_code"], 40 | 'continent_code'=>$row["continent_code"], 41 | 'continent_name'=>$row["continent_name"], 42 | 'country_code'=>$row["country_code"], 43 | 'country_name'=>$row["country_name"], 44 | 'subdivision_1_iso_code'=>$row["subdivision_1_iso_code"], 45 | 'state_abbr'=>$row["subdivision_1_iso_code"], 46 | 'subdivision_1_name'=>$row["subdivision_1_name"], 47 | 'state_name'=>$row["subdivision_1_name"], 48 | 'subdivision_2_iso_code'=>$row["subdivision_2_iso_code"], 49 | 'subdivision_2_name'=>$row["subdivision_2_name"], 50 | 'city_name'=>$row["city_name"], 51 | 'metro_code'=>$row["metro_code"], 52 | 'time_zone'=>$row["time_zone"], 53 | 'is_in_european_union'=>$row["is_in_european_union"] 54 | ) 55 | ); 56 | } 57 | $rowsReturned = $sql->rowCount(); 58 | if ($rowsReturned > 0) { 59 | header('Content-Type: application/json; charset=utf-8'); 60 | echo json_encode($json, JSON_PRETTY_PRINT); 61 | } else { 62 | $json = array( 63 | 'status'=>404, 64 | 'message'=>'Not Found', 65 | 'error'=>array( 66 | 'code'=>404, 67 | 'reserved_ip'=>false, 68 | 'ip'=>$geoip, 69 | 'message'=>'IP GeoIP data could not be found' 70 | ) 71 | ); 72 | header('Content-Type: application/json; charset=utf-8'); 73 | echo json_encode($json, JSON_PRETTY_PRINT); 74 | } 75 | } else { 76 | $json = array( 77 | 'status'=>400, 78 | 'message'=>'Bad Request', 79 | 'error'=>array( 80 | 'code'=>404, 81 | 'reserved_ip'=>true, 82 | 'ip'=>$geoip, 83 | 'message'=>'IP Reserved' 84 | ) 85 | ); 86 | header('Content-Type: application/json; charset=utf-8'); 87 | echo json_encode($json, JSON_PRETTY_PRINT); 88 | } 89 | } else { 90 | $json = array( 91 | 'status'=>400, 92 | 'message'=>'Bad Request', 93 | 'error'=>array( 94 | 'code'=>404, 95 | 'reserved_ip'=>false, 96 | 'ip'=>null, 97 | 'message'=>'Non IP input data' 98 | ) 99 | ); 100 | header('Content-Type: application/json; charset=utf-8'); 101 | echo json_encode($json, JSON_PRETTY_PRINT); 102 | } 103 | 104 | ?> -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 17 | 18 |
19 |