分類
好用軟體

IP調查小程式-功能新增

之前介紹了使用 Cloudflare worker來進行客戶端 IP調查的小程式(https://diary.tw/archives/2182), 最近新增一些功能上來.

  1. 利用瀏覽器訪問時, 會加上完整的 html, 並增加了 Google Analytics 追蹤碼, 來記錄使用的次數.
  2. 若是利用非瀏覽器訪問時, 會直接輸出純文字 ip 而不會加上其他的內容, 例如: curl https://ip.diary.tw/
  3. 利用這個 geoplugin 這個免費的 API 功能來查找對應 IP的資訊, 請參考這個 API文件說明: https://www.geoplugin.com/webservices/json, 使用方式為 https://ip.diary.tw/?data=geo, 可以查找對應 IP的所在地與該地區使用貨幣與匯率. 輸出範例如下:
{
  "geoplugin_request":"12.34.56.78",
  "geoplugin_status":200,
  "geoplugin_delay":"1ms",
  "geoplugin_credit":"Some of the returned data includes GeoLite2 data created by MaxMind, available from <a href='https:\/\/www.maxmind.com'>https:\/\/www.maxmind.com<\/a>.",
  "geoplugin_city":"New Taipei City",
  "geoplugin_region":"New Taipei City",
  "geoplugin_regionCode":"NWT",
  "geoplugin_regionName":"New Taipei City",
  "geoplugin_areaCode":"",
  "geoplugin_dmaCode":"",
  "geoplugin_countryCode":"TW",
  "geoplugin_countryName":"Taiwan",
  "geoplugin_inEU":0,
  "geoplugin_euVATrate":false,
  "geoplugin_continentCode":"AS",
  "geoplugin_continentName":"Asia",
  "geoplugin_latitude":"24.9466",
  "geoplugin_longitude":"121.586",
  "geoplugin_locationAccuracyRadius":"20",
  "geoplugin_timezone":"Asia\/Taipei",
  "geoplugin_currencyCode":"TWD",
  "geoplugin_currencySymbol":"NT$",
  "geoplugin_currencySymbol_UTF8":"NT$",
  "geoplugin_currencyConverter":32.0408
}

 

請大家多加利用 IP查找小功具: https://ip.diary.tw

 

[2026/5/30 10:36]

由於原來的 ip geolocation service 已變成只有付費方案了如下:

{
  "geoplugin_status":403,
  "geoplugin_message": "geoPlugin API is no longer available for free use. To continue access, please upgrade to a paid plan",
  "geoplugin_url": "https://www.geoplugin.com/subscription"
}

 

所以改用仍有 free tier 的另一個服務: https://ipgeolocation.io/, 免費就有一定的使用量可供應用, API 也簡單, 只需要註冊帳戶, 就可以拿 API Token 去訪問取得資訊, API 使用方式請參考:

https://ipgeolocation.io/documentation/ip-location-api.html

調整一下程式碼, 之後訪問 https://ip.diary.tw/?data=geo 時, 就可以拿到對應的回傳結果如下:

{
  "ip": "12.34.56.78",
  "location": {
    "continent_code": "AS",
    "continent_name": "Asia",
    "country_code2": "TW",
    "country_code3": "TWN",
    "country_name": "Taiwan",
    "country_name_official": "Republic of China",
    "country_capital": "Taipei",
    "state_prov": "New Taipei City",
    "state_code": "TW-NWT",
    "district": "Banqiao District",
    "city": "New Taipei City",
    "zipcode": "231",
    "latitude": "24.97828",
    "longitude": "121.53948",
    "is_eu": false,
    "country_flag": "https://ipgeolocation.io/static/flags/tw_64.png",
    "geoname_id": "11697228",
    "country_emoji": "🇹🇼"
  },
  "country_metadata": {
    "calling_code": "+886",
    "tld": ".tw",
    "languages": [
      "zh-TW",
      "zh",
      "nan",
      "hak"
    ]
  },
  "currency": {
    "code": "TWD",
    "name": "New Taiwan Dollar",
    "symbol": "NT$"
  },
  "asn": {
    "as_number": "AS38841",
    "organization": "kbro CO. Ltd.",
    "country": "TW"
  },
  "time_zone": {
    "name": "Asia/Taipei",
    "offset": 8,
    "offset_with_dst": 8,
    "current_time": "2026-05-30 10:34:55.910+0800",
    "current_time_unix": 1780108495.91,
    "current_tz_abbreviation": "CST",
    "current_tz_full_name": "Taipei Standard Time",
    "standard_tz_abbreviation": "CST",
    "standard_tz_full_name": "Taipei Standard Time",
    "is_dst": false,
    "dst_savings": 0,
    "dst_exists": false,
    "dst_tz_abbreviation": "",
    "dst_tz_full_name": "",
    "dst_start": {},
    "dst_end": {}
  }
}

資訊更多元更豐富了, 歡迎多加利用.

[2026/8/17 7:20]

原來在 Cloudflare 中有 request.cf 變數(可參考: https://developers.cloudflare.com/workers/runtime-apis/request/),裡面也有對應的地理資訊,新增 https://ip.diary.tw/?data=geo2 範例資料如下:

{
  "httpProtocol": "HTTP/2",
  "clientAcceptEncoding": "gzip, deflate, br",
  "requestPriority": "weight=42;exclusive=0;group=0;group-weight=0",
  "edgeRequestKeepAliveStatus": 1,
  "requestHeaderNames": {},
  "clientTcpRtt": 12,
  "clientQuicRtt": 0,
  "colo": "TPE",
  "asn": 38841,
  "asOrganization": "kbro CO. Ltd.",
  "country": "TW",
  "isEUCountry": false,
  "city": "Banqiao",
  "continent": "AS",
  "region": "Taipei",
  "regionCode": "TPE",
  "timezone": "Asia/Taipei",
  "longitude": "121.46719",
  "latitude": "25.01427",
  "tlsVersion": "TLSv1.3",
  "tlsCipher": "AEAD-AES128-GCM-SHA256",
  "tlsClientRandom": "iZQjjbMHDvqj7bV9mGrvFOLCfcVTM7EfuEhmcEf6biE=",
  "tlsClientCiphersSha1": "Ycpx9ze2EIngjFvfLFng3z8MFzM=",
  "tlsClientExtensionsSha1": "fmoiUXxub2JA3Bd4T7jJ6OCQJ/s=",
  "tlsClientExtensionsSha1Le": "75rYBxmWw7lFoVazIKaJJGtd1xc=",
  "tlsExportedAuthenticator": {
    "clientHandshake": "d9433345ccb61cda32fc50991665f17c63e3f1d63d7bf8ef016c552543ee0920",
    "serverHandshake": "948cc32b3413616b0a331ed886a26abca9625c85e753afb790711648aa0497d4",
    "clientFinished": "90eb15c16b0812c9168d858e7d02b142a8358b1480766efb85b37479d74a41fa",
    "serverFinished": "1df4bd5176a49fbfd4f40e2b04827eed5e0a32ef520a1d4934cabd915f2ea9b4"
  },
  "tlsClientHelloLength": "1885",
  "tlsClientAuth": {
    "certPresented": "0",
    "certVerified": "NONE",
    "certRevoked": "0",
    "certIssuerDN": "",
    "certSubjectDN": "",
    "certIssuerDNRFC2253": "",
    "certSubjectDNRFC2253": "",
    "certIssuerDNLegacy": "",
    "certSubjectDNLegacy": "",
    "certSerial": "",
    "certIssuerSerial": "",
    "certSKI": "",
    "certIssuerSKI": "",
    "certFingerprintSHA1": "",
    "certFingerprintSHA256": "",
    "certNotBefore": "",
    "certNotAfter": "",
    "certRFC9440": "",
    "certRFC9440TooLarge": false,
    "certChainRFC9440": "",
    "certChainRFC9440TooLarge": false
  },
  "verifiedBotCategory": "",
  "edgeL4": {
    "deliveryRate": 284711
  }
}

 

大家也可以多加利用!

分類
Javascript

利用Cloudflare worker來進行客戶端IP查找

Cloudflare 有個功能, 就是在 edge 端的 worker, 可以參考:

https://developers.cloudflare.com/workers/

我們可以利用這個 worker 來做許多功能, 把它想成小型的在邊緣的處理器, 先來看一些 example 好了:

https://developers.cloudflare.com/workers/examples/

理解可以在這個 worker 處理不少事情後, 接下來實做一個簡單的功能, 像是這種取客戶端 IP 的功能:

早期也有利用 PHP 寫過取 IP 功能的小程式, 可以參考:

不過這裡要介紹的是利用 cloudflare 的 worker 來進行.

分類
程式技術

正則表式法表示ip區間

使用正則表示法來表示一個 ip 區間, 例如: 1.2.3.1~64 這樣的表示方式為:

^1\.2\.3\.([1-9]|[1-5][0-9]|6[1-4])$

另外也會有這樣的寫法: (下面是”流量的秘密”這本書中的第246頁寫的, 不過比較有效率的寫法應為上面, 實際上使用最後的 google analytics 的說明幫助頁上產生的亦同上)

^1\.2\.3\.([1-9]|[1-5][0-9]|[1-6][1-4])$

這是因為在 google-analytics中, 若需要新增設定檔用來排除某 ip, 或某區段 ip 時會用到, 如下畫面:
這樣可以很方便的進行某區段的 ip 篩選, 其實 google analytics 的說明幫助頁也有這個功能, 很方便, 自動可以產生某區段 ip 的正則表示法(或稱規則運算式): https://www.google.com/support/googleanalytics/bin/answer.py?answer=55572&hl=zh_TW&utm_id=ad

若需要試看看對不對, 可以利用線上工具來測試: http://www.regexplanet.com/simple/index.html.

分類
FreeBSD/Linux

apache deny ip設定

想要將 apache 的站台, 拒絕讓某個(某群ip)存取的方式, 有幾個方法, 其中最單純最俱體的方式就是直接利用 <Directory></Directory> 這個 tag 中的限制存取來操作最為單純方便 (當然, 虛擬主機可不行, 可以直接利用 .htaccess 設定該層目錄的存取權限)

一般來設, 設定如下:

<Directory "/usr/home/website1">
  order deny,allow
</Directory>

這樣即可. 就是判斷 deny , 預設為 allow 的條件, 也就是所謂公開站台的設定, 若有要限制某些 ip 存取, 可以這樣下:

<Directory "/usr/home/website1">
  order deny,allow
  deny from 1.2.3.4
  deny from 11.22.33.
</Directory>

其中的 deny from 1.2.3.4 是限制某個單一 ip, 而 deny from 11.22.33. 是指 11.22.33.* 都是拒絕存取的, 如此一來, 便能有效管理不想讓某些 ip (例如爬蟲類或是一些吃資源的 ip, 又或是攻擊的 ip)訪問做好限制.

不過發生了一個有趣的狀況, 也就是之前設了, 發現沒有用, 在多次交叉比對檢查後, 發現是這個原因, 就是在 <VirtualHost> 內的 DocumentRoot 指定為 /home/website1 而在 <Directory> 內的目錄指向是 /usr/home/website1 , 這樣一來, apache 在存取該 website1 的檔案時, 是走 /home/website1 下的檔案, 雖然和 /usr/home/website1 一樣, 不過對 apache 來說卻是不同, 這個要特別注意才行, 否則可能會有設定好的 <Directory> 的限制 ip, 但實際上沒有作用, 原因就有可能發生在這裡了.

又或反過來說, 設定的路徑一定要一致, 而且儘量用完整路徑, 不要用簡化的 link 路徑指向檔案, 也比較容易除錯一些. 所以原則上是這樣的:

<VirtualHost *:80>
  ServerName test.diary.tw
  Document /usr/home/www/test
.....
</VirtualHost>

<Directory "/usr/home/www/test">
  order deny,allow
  deny from 1.2.3.4
</Directory>

這樣就 ok 啦, 千萬要注意紅字部分要一致的這件事, 否則可能設了沒有作用, 原因就在這裡了..

另外補充一下, 若是這種方式限制存取的話, client 會拿到 403 的存取失敗代碼.