2010-05-11 35 views
27

Tôi đang tự hỏi nếu điều này là cách tốt nhất để phù hợp với một chuỗi bắt đầu với một (Regex Perl-style) địa chỉ IP riêng:Private IP Address Định danh trong Regular Expression

(^127\.0\.0\.1)|(^192\.168)|(^10\.)|(^172\.1[6-9])|(^172\.2[0-9])|(^172\.3[0-1]) 

Cảm ơn nhiều!

+3

Trước tiên, bạn nên xem lại RFC1918 để có được danh sách thích hợp. Thứ hai, tôi đề nghị rằng một giải pháp không liên quan đến regexps sẽ dễ bảo trì hơn. Khi bạn chuyển đổi một địa chỉ IP thành số, nó khá dễ dàng để so khớp nó với một danh sách các dải IP riêng. Điều này cũng sẽ cho phép bạn dễ dàng sử dụng danh sách bogon công khai có sẵn, chứa nhiều hơn RFC1918. – derobert

+1

@derobert đúng, nhưng đối với các công dụng như Bộ lọc Địa chỉ Từ xa Tomcat, bạn cần một cụm từ thông dụng. – Raedwald

+0

Đó là một lỗi mới bắt đầu phổ biến để suy nghĩ '^' có nghĩa là "không" trong ngữ cảnh này, vì vậy nó chỉ ra: Mỗi '^' trong biểu thức của bạn chỉ đơn giản là neo khớp với đầu dòng. Trong regex truyền thống, không có cách nào đơn giản để nói "không phải chuỗi này" mặc dù các biểu thức tương thích Perl/PCRE có các dấu hiệu tiêu cực với '(?! ...)' – tripleee

Trả lời

48

Tôi giả định bạn muốn kết hợp các phạm vi:

 
127. 0.0.0 – 127.255.255.255  127.0.0.0 /8 
10. 0.0.0 – 10.255.255.255  10.0.0.0 /8 
172. 16.0.0 – 172. 31.255.255 172.16.0.0 /12 
192.168.0.0 – 192.168.255.255 192.168.0.0 /16 

bạn đang thiếu một số dấu chấm có thể gây ra nó để chấp nhận ví dụ 172.169.0.0 mặc dù điều này không nên được chấp nhận. Tôi đã sửa nó bên dưới. Loại bỏ các dòng mới, nó chỉ cho dễ đọc.

(^127\.)| 
(^10\.)| 
(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)| 
(^192\.168\.) 

Cũng lưu ý rằng điều này giả định rằng các địa chỉ IP đã được xác nhận - nó chấp nhận những thứ như 10.foobar.

+0

Nếu bạn muốn loại trừ địa chỉ IP riêng tư khỏi theo dõi phân tích google, hãy sử dụng địa chỉ này: https://gist.github.com/1000402 –

+2

Dòng đầu tiên phải là (^ 127 \.) | –

+0

Nó không xác thực đối với các mạng IP nội bộ của chúng tôi: Ví dụ: 10.131.43.84 Khối 10 của bạn bị hỏng – mfriis

3

Có vẻ đúng. Cá nhân, tôi muốn thay đổi người đầu tiên:

^127\.0 

Với điều này: (^127\.0\.0\.1) Bạn đang tìm kiếm bất cứ thứ gì bắt đầu với 127.0.0.1 và sẽ bỏ lỡ 127.0.0.2*, 127.0.2.*, 127.0.*, vv

+2

Tôi biết điều này là cũ, nhưng câu hỏi này là thứ nhất hoặc thứ hai trên tìm kiếm google của tôi. Tôi tin rằng toàn bộ khối 127.0.0.0/8 được dành riêng cho loopback, do đó 0 thậm chí không nên ở đó. –

3

Đây là trường hợp bạn quyết định đi với nhận xét của tôi, cho thấy bạn không sử dụng regexps. Chưa được kiểm tra (nhưng có lẽ làm việc, hoặc ít nhất là đóng), trong Perl:

@private = (
    {network => inet_aton('127.0.0.0'), mask => inet_aton('255.0.0.0') }, 
    {network => inet_aton('192.168.0.0'), mask => inet_aton('255.255.0.0') }, 
    # ... 
); 

$ip = inet_aton($ip_text); 
if (grep $ip & $_->{mask} == $_->{network}, @private) { 
    # ip address is private 
} else { 
    # ip address is not private 
} 

Note tại như thế nào @private chỉ là dữ liệu mà bạn có thể dễ dàng thay đổi. Hoặc tải xuống khi đang bay từ Cymru Bogon Reference.

chỉnh sửa: Nó xảy ra với tôi rằng yêu cầu một regexp Perl không có nghĩa là bạn biết Perl, do đó, dòng chính là có 'grep', mà chỉ lặp trên mỗi dải địa chỉ riêng. Bạn lấy IP của bạn, bitwise và nó với mặt nạ mạng, và so sánh với địa chỉ mạng. Nếu bằng nhau, một phần của mạng riêng đó.

13

Điều này giống với câu trả lời đúng của Mark, nhưng hiện bao gồm địa chỉ riêng IPv6.

/(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/ 
+4

Không tốt - Theo Wikipedia, (http://en.wikipedia.org/wiki/Unique_local_address), khối (fc00 ::/7) được dành riêng cho Địa chỉ Địa phương Duy nhất. Regex này chỉ thêm địa chỉ localhost (:: 1) vào giải pháp được chấp nhận. – dana

+3

Theo https://github.com/rails/rails/pull/12651/files regexp cho điều này sẽ là '^ [fF] [cCdD]' - Tôi đang chỉnh sửa câu trả lời cho phù hợp. – blueyed

+0

Ký tự '/' ở đầu và ở cuối tập lệnh đề xuất tôi rằng bạn đang sử dụng cụm từ trong một số ngôn ngữ như Javascript, nhưng điều đó không hợp lệ ở các ngôn ngữ khác. Mặc dù vậy, một phiên bản ngắn hơn (và không có dấu gạch chéo) là '^ (127 \.) | (192 \ .168 \.) | (10 \.) | (172 \ .1 [6-9] \.) | (172 \ .2 [0-9] \.) | (172 \ .3 [0-1] \.) | (:: 1 $) | ([fF] [cCdD]) ' – Mrdev

8

Tôi đã tạo ra

REGEXP này CHO MẠNG CLASS A:

(10)(\.([2]([0-5][0-5]|[][6-9])|[1][0-9][0-9]|[1-9][0-9]|[0-9])){3}

REGEXP CHO MẠNG CLASS B:

(172)\.(1[6-9]|2[0-9]|3[0-1])(\.([2][0-5][0-5]|[1][0-9][0-9]|[1-9][0-9]|[0-9])){2}

REGEXP CHO MẠNG CLASS C :

(192)\.(168)(\.[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]){2}

Hãy cho tôi biết nếu bạn gặp bất kỳ lỗi

Nếu bạn chắc chắn về đầu ra của bạn (nói ví dụ netstat) và bạn không cần phải kiểm tra về tính hợp lệ địa chỉ IP bởi vì nó đã được thực hiện , sau đó bạn có thể bắt các địa chỉ IP riêng với công thức này

grep -P "(10. | 192.168 | 172.1 [6-9]. | 172.2 [0-9]. | 172.3 [01].). *"

+3

Bằng cách sử dụng' [ 2] [0-5] [0-5] 'trong phạm vi 200 đến 255, các số như 206 đến 209 và 216 đến 219, v.v. sẽ không khớp. Bạn sẽ phải thay thế bằng '([0-9] | [1-9] [0-9] | 1 [0-9] [0-9] | 2 [0-4] [0-9] | 25 [0-5]) '. – kielabokkie

+0

Ngôn ngữ này được sử dụng cho mục đích gì? Tôi không thể làm cho nó hoạt động, https://regex101.com/r/jdVmny/1 – Justin

1

Nếu bạn đang tìm kiếm system.net defaultProxy và cấu hình danh sách bỏ qua proxy có sử dụng một proxy cho bên ngoài nhưng sử dụng kết nối trực tiếp với máy chủ nội bộ (có thể làm với một số hỗ trợ ipv6) ...

<system.net> 
    <defaultProxy enabled="true"> 
    <proxy proxyaddress="http://proxycluster.privatedomain.net:8080" bypassonlocal="True" /> 
    <bypasslist> 
     <!-- exclude local host --> 
     <add address="^(http|https)://localhost$" /> 
     <!-- excludes *.privatedomain.net --> 
     <add address="^(http|https)://.*\.privatedomain\.net$" /> 
     <!-- excludes simple host names --> 
     <add address="^(http|https)://[a-z][a-z0-9\-_]*$" /> 
     <!-- exclude private network addresses 192.168, 172.16..31 through 31, 127.* etc. --> 
     <add address="^(http|https)://((((127)|(10))\.[0-9]+\.[0-9]+\.[0-9]+)|(((172\.(1[6-9]|2[0-9]|3[0-1]))|(192\.168))\.[0-9]+\.[0-9]+))$"/> 
    </bypasslist> 
    </defaultProxy> 
    <connectionManagement> 
    <add address="*" maxconnection="10" /> 
    </connectionManagement> 
</system.net> 
-1

FWIW mô hình này là trên 10% nhanh hơn sử dụng pattern.matcher:

^1((0)|(92\\.168)|(72\\.((1[6-9])|(2[0-9])|(3[0-1])))|(27))\\. 
+1

Tôi đã thực hiện một số thử nghiệm nhưng dường như nó chậm hơn 100%. Bạn có thể cung cấp một số xét nghiệm để sao lưu điều này không? –

0
 //RegEx to check for the following ranges. IPv4 only 
     //172.16-31.xxx.xxx 
     //10.xxx.xxx.xxx 
     //169.254.xxx.xxx 
     //192.168.xxx.xxx 

    var regex = /(^127\.)|(^(0)?10\.)|(^172\.(0)?1[6-9]\.)|(^172\.(0)?2[0-9]\.)|(^172\.(0)?3[0-1]\.)|(^169\.254\.)|(^192\.168\.)/; 
2

đây là những gì tôi sử dụng trong python:

rfc1918 = re.compile('^(10(\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[0-9]{1,2})){3}|((172\.(1[6-9]|2[0-9]|3[01]))|192\.168)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[0-9]{1,2})){2})$') 

bạn có thể loại bỏ các^và/hoặc $ neo nếu bạn muốn.

Tôi thích regex ở trên vì nó xóa các octet không hợp lệ (bất kỳ thứ gì trên 255).

ví dụ sử dụng:

if rfc1918.match(ip): 
    print "ip is private" 
Các vấn đề liên quan