2013-04-12 21 views
20

Ứng dụng của chúng tôi sử dụng WCF trên các đường ống được đặt tên để giao tiếp giữa hai quy trình (lưu ý: không phải là quá trình là một dịch vụ Windows.) Ứng dụng của chúng tôi đã chạy trong lĩnh vực này mà không có sự cố trong một vài năm nay.Ứng dụng của chúng tôi phá vỡ ứng dụng WCF của chúng tôi

Chúng tôi hiện đang nhận được báo cáo rằng sự hiện diện của một ứng dụng của bên thứ ba (cụ thể là Garmin Express) đang phá vỡ chúng tôi. Tôi đã cài đặt Garmin Express trong nhà và xác nhận hành vi. Cụ thể là "Dịch vụ cập nhật cốt lõi của Garmin", khi chạy, khiến ứng dụng của chúng tôi thất bại.

Khi dịch vụ Garmin đang chạy, phía "dịch vụ" của ứng dụng của chúng tôi bắt đầu và không có vấn đề gì khi tạo điểm cuối WCF. Nhưng khi máy khách khởi động và cố gắng kết nối với dịch vụ, nó không thành công với EndpointNotFoundException, như thể dịch vụ đó thậm chí không chạy.

Tại thời điểm này, tôi thực sự có thể dừng dịch vụ Garmin từ bảng điều khiển Dịch vụ, sau đó chạy lại máy khách thành công mà không cần khởi động lại dịch vụ của chính chúng tôi. Nếu tôi bắt đầu lại dịch vụ Garmin, các nỗ lực khác để khởi động máy khách thất bại. Vì vậy, điều này ít nhất chứng minh rằng dịch vụ WCF của chúng tôi là lên và chạy toàn bộ thời gian, và phần mềm Garmin bằng cách nào đó ngăn chặn khả năng của khách hàng của chúng tôi để kết nối với nó.

Chúng tôi đang sử dụng tên riêng của mình cho địa chỉ điểm cuối (ví dụ: "net.pipe: // localhost/MyPrivateApplication"). Tôi đã thử thay đổi địa chỉ này thành nhiều tên khác, nhưng điều đó không ảnh hưởng đến vấn đề này.

Làm cách nào để có thể áp dụng một ứng dụng khác, đơn giản bằng cách chạy, phá vỡ khả năng của ứng dụng của riêng chúng tôi khi sử dụng WCF?

Cập nhật: theo yêu cầu, đây là đoạn mã từ phía dịch vụ. Tôi đã đơn giản hóa nó từ mã ban đầu của chúng tôi trong một nỗ lực để cô lập vấn đề. Cho đến nay, không một thay đổi duy nhất tôi đã thực hiện đã có bất kỳ ảnh hưởng nào đến vấn đề này.

MyService service = new MyService(); 
ServiceHost host = new ServiceHost(service); 
string hostAddress = new Uri("net.pipe://localhost/MyWCFConnection"); 
host.AddServiceEndpoint(typeof(IMyService), new NetNamedPipeBinding(), hostAddress); 
host.Open(); 
+0

Dịch vụ của bạn chỉ định URL dịch vụ của dịch vụ như thế nào? Có phải là địa chỉ cơ sở + địa chỉ tương đối hoặc địa chỉ absoute không? Có lẽ bạn có thể đăng các trích xuất từ ​​mã/cấu hình cho biết điểm cuối dịch vụ của bạn được thiết lập như thế nào. –

+0

Tôi đã cập nhật bài đăng của mình bằng đoạn mã. Tôi khá chắc chắn đây là một địa chỉ tuyệt đối, đúng không? Một lần nữa, mã phía dịch vụ này thực hiện thành công cho dù dịch vụ Garmin đang chạy hay không. Chỉ phía máy khách bị ảnh hưởng. – ObjetDart

+0

Vâng, đó là một địa chỉ tuyệt đối, vì vậy có một cái gì đó tinh tế hơn xảy ra hơn đề nghị đầu tiên của tôi. –

Trả lời

12

Một câu trả lời có thể cho câu hỏi của bạn "Làm thế nào có thể ứng dụng khác, chỉ đơn giản bằng cách chạy, phá vỡ ứng dụng riêng của chúng tôi ...":

  1. Các ứng dụng khác cũng sử dụng WCF NetNamedPipeBinding.
  2. Cả hai ứng dụng đều tạo điểm cuối dịch vụ bằng cách sử dụng URL cơ bản + tương đối.
  3. Lựa chọn của ứng dụng về địa chỉ cơ sở và HostNameComparisonMode là sao cho có xung đột tên giữa các ứng dụng trên one of the URL variants used by the client-side WCF stack to locate the metadata for the service.

Tôi không biết liệu dịch vụ Garmin có thực sự sử dụng WCF NetNamedPipeBinding hay không, nhưng đây là một khả năng bạn nên điều tra. Vấn đề có thể tránh được bằng cách luôn luôn using absolute URLs for NetNamedPipe endpoints.


OK, vì vậy sau khi cập nhật cho câu hỏi, bây giờ chúng ta biết rằng dịch vụ Garmin đang sử dụng WCF NetNamedPipeBinding, và chúng tôi biết rằng ứng dụng của bạn đăng ký dịch vụ của mình sử dụng một địa chỉ tuyệt đối, vì vậy giải thích ở trên không phải là câu chuyện hoàn chỉnh.

Dưới đây là một giả thuyết:

  1. Giả sử dịch vụ Garmin chạy trong một quá trình trong đó có các đặc quyền an ninh SeCreateGlobalPrivilege (mà một dịch vụ Windows sẽ phải trừ đặc biệt mã hoá để vô hiệu hóa các đặc quyền).
  2. Giả sử nó cũng đăng ký điểm cuối WCF có tên của nó với địa chỉ cơ sở là net.pipe: // localhost và địa chỉ điểm cuối tương đối.
  3. Bây giờ siêu dữ liệu dịch vụ của nó sẽ được xuất bản bằng cách sử dụng đối tượng ánh xạ bộ nhớ dùng chung với tên trong không gian tên Chung.
  4. Ứng dụng dịch vụ của bạn không phải là dịch vụ Windows. Giả thuyết của tôi là quá trình của nó không có đặc quyền bảo mật SeCreateGlobalPrivilege. Trong trường hợp này, siêu dữ liệu dịch vụ của nó sẽ được xuất bản bằng cách sử dụng đối tượng ánh xạ bộ nhớ dùng chung trong không gian tên Phiên cục bộ của nó.
  5. Bây giờ quá trình khách hàng của bạn cố gắng khởi tạo kết nối khi dịch vụ Garmin đang chạy ... ngăn xếp kênh phía máy khách WCF Phần tử NetNamedPipeBinding cố định vị trí siêu dữ liệu dịch vụ cho dịch vụ của bạn dựa trên URL dịch vụ của bạn net.pipe: // localhost/MyWCFConnection. Như được giải thích trong liên kết ở trên, nó sẽ thực hiện tìm kiếm bằng cách sử dụng các biến thể khác nhau của URL dịch vụ để tìm ra tên cho đối tượng bộ nhớ chia sẻ có chứa siêu dữ liệu. Nó lần đầu tiên tìm trong không gian tên toàn cầu, để có danh sách đầy đủ các biến thể, trước khi nhìn vào không gian tên cục bộ.
  6. Trong trường hợp này, lần thử đầu tiên sẽ là tên bắt nguồn từ "net.pipe: // +/MyWCFConnection" và có lẽ không tìm được đối tượng có tên này trong không gian tên chung.
  7. Tuy nhiên, lần thử thứ hai sẽ dựa trên biến thể "net.pipe: // + /" và điều này sẽ khớp với tên bản đồ bộ nhớ chia sẻ của dịch vụ Garmin được xuất bản trong không gian tên Chung. Do thứ tự tìm kiếm, nó sẽ không bao giờ nhận được siêu dữ liệu dịch vụ của bạn được xuất bản trong không gian tên Phiên cục bộ.
  8. Khách hàng của bạn cố gắng kết nối với đường ống của dịch vụ Garmin. Giả sử dịch vụ Garmin có một số bảo mật được triển khai, kết quả là khách hàng của bạn bị từ chối với Truy cập bị từ chối (ví dụ: có thể set an ACL on its pipe). Kết quả cũng có thể bề mặt như một EndpointNotFoundException. [LATER EDIT: Thực ra, rất có thể những gì đang xảy ra là khách hàng của bạn đang thực sự kết nối với dịch vụ Garmin, bắt đầu bắt tay mở đầu giao thức khung và nhận lại lỗi giao thức khung (http://schemas.microsoft.com/ws/2006/05/framing/faults/EndpointNotFound) vì URL được yêu cầu trong bản ghi Via sẽ không khớp với những gì mà dịch vụ Garmin đang mong đợi. Việc ràng buộc sau đó là bỏ kết nối và hiển thị lỗi này cho mã khách hàng của bạn dưới dạng EndpointNotFoundException.]

Bạn có thể làm gì với nó? Tôi sẽ đề xuất:

  • Nếu giả thuyết trên hoặc tương tự có thể được xác nhận và Garmin đang sử dụng địa chỉ tương đối cơ sở với cơ sở chỉ net.pipe: // localhost, tốt nhất là nên sở hữu chúng vấn đề: họ có thể khắc phục vấn đề như vậy rất dễ dàng bằng cách thay đổi địa chỉ cơ sở của họ thành một thứ có nhiều khả năng là duy nhất.
  • Bạn có thể làm việc xung quanh nó bằng cách tìm cách để ứng dụng dịch vụ của bạn chạy với đặc quyền bảo mật SeCreateGlobalPrivilege: điều này không dễ dàng mà không làm cho nó trở thành dịch vụ Windows hoặc chạy với tư cách Quản trị viên, nhưng có lẽ không phải là không thể. Sau đó, siêu dữ liệu của bạn cũng sẽ được xuất bản trong không gian tên toàn cầu và tìm kiếm của khách hàng sẽ tìm thấy nó trước khi Garmin.
  • [Chỉnh sửa sau] Có thể có một giải pháp liên quan đến việc đặt thuộc tính HostNameComparisonMode của liên kết thành Chính xác và sử dụng một từ đồng nghĩa cho localhost làm phần lưu trữ của URL dịch vụ (ví dụ: net.pipe: //127.0.0.1/MyWCFConnection). Điều này có thể chỉ đạo tìm kiếm xung quanh các biến thể Garmin để khách hàng của bạn có cơ hội xem xét tên trong không gian tên Phiên cục bộ. Tôi không biết rằng nó sẽ làm việc, nhưng đáng thử, tôi đã có thể nghĩ.
  • Và ảnh rất dài: Công ty của bạn có mối quan hệ hỗ trợ sản phẩm với Microsoft không?Có thể cho rằng đây là một lỗ hổng thiết kế nghiêm trọng trong WCF: nếu bạn lo lắng về điều đó, bạn có thể khiến Microsoft phát hành một bản vá QFE cho nó, ví dụ: để cung cấp một thuộc tính ràng buộc để báo cho ngăn xếp phía máy khách chỉ thử dùng không gian tên cục bộ.
+0

Tôi khá chắc chắn Dịch vụ Garmin cũng đang sử dụng WCF NetNamedPipeBinding, dựa trên thông tin trong [bài viết này] (http://blogs.msdn.com/b/rodneyviana/archive/2011/03/22/named-pipes -in-wcf-được-đặt tên-nhưng-không-by-bạn-và-how-to-tìm-the-thực-windows-object-name.aspx). Khi dịch vụ Garmin được khởi động, một đường ống mới có tên sẽ xuất hiện với cùng tên kiểu GUID giống như bạn nhận được với các dịch vụ WCF khác sử dụng các đường ống có tên. – ObjetDart

+0

Tôi đã xác nhận rằng sự cố sẽ biến mất nếu tôi chạy quy trình bên dịch vụ là Quản trị viên. Điều đó chắc chắn cho vay hỗ trợ cho lý thuyết thứ hai của bạn. Điều này sẽ không giúp chúng tôi giải quyết vấn đề trong lĩnh vực này nhưng ít nhất chúng tôi có một lời giải thích có thể ngay bây giờ. – ObjetDart

+0

Vì vậy, có vẻ như chúng tôi đang mắc kẹt. Chúng ta cần phải khắc phục vấn đề này trong lĩnh vực này, chúng tôi không thể chờ đợi cho Garmin có thể hoặc có thể không sửa chữa nó trong thời gian rảnh rỗi của chu kỳ phát hành sản phẩm của họ, có thể là vài tháng hoặc thậm chí nhiều năm. Phần xử lý phía dịch vụ của sản phẩm của chúng tôi chạy dưới tài khoản của người dùng cuối, vì vậy AFAIK không có cách nào để chạy nó với SeCreateGlobalPrivilege. – ObjetDart

6

Hiện tại Microsoft đã xóa bỏ vấn đề theo cách mà Dịch vụ cập nhật cốt lõi của Garmin tạo ra các đường ống có tên. Ống có tên có thể được tạo ra trong các phạm vi khác nhau - Toàn cầu và địa phương. Phạm vi toàn cầu về cơ bản là máy rộng và địa phương cụ thể cho người dùng. Ứng dụng của Garmin là

a. chạy như dịch vụ hệ thống, do đó, phạm vi để nghe dịch vụ ống tên là toàn cầu.

b. nghe trên địa chỉ gốc của “net.pipe: // localhost /” (ví dụ: không có bất kỳ đường dẫn/phân đoạn phụ nào).

c. Sử dụng chế độ so sánh tên máy chủ lưu trữ StrongWildcard.

d. Các mục từ a đến c có nghĩa là ứng dụng của Garmin về cơ bản là thiết bị bắt kịp cho bất kỳ kết nối đường ống net nào không khớp với một cái gì đó cụ thể hơn.

e. Nó cũng có nghĩa là Garmin chặn hoàn toàn tất cả người nghe đang sử dụng phạm vi cục bộ

Việc sửa lỗi lý tưởng cho điều này sẽ là một thay đổi trong ứng dụng Garmin sao cho đăng ký trình nghe net.pipe với url cụ thể hơn.

+2

Tôi nghĩ Microsoft nên lên kế hoạch sửa chữa hoặc sửa chữa nó. Chúng tôi chỉ thấy rằng dịch vụ "Dịch vụ khung giải pháp hỗ trợ của HP" cũng đang gây ra sự cố này. – Pep

4

Tôi đã tìm thấy một phương pháp để hiển thị những ứng dụng nào sử dụng net.pipe (mặc dù không nhất thiết phải sử dụng nó không chính xác).

Đầu tiên tải về các ứng dụng Xử lý từ Sysinternals:

https://technet.microsoft.com/en-us/sysinternals/handle.aspx?f=255&MSPPError=-2147217396

Sau đó mở một dấu nhắc lệnh as administrator, và chạy "Handle.exe net.pipe" (trừ dấu ngoặc kép). Điều này sẽ liệt kê tất cả các ứng dụng bằng cách sử dụng net.pipe hiện đang chạy. Từ đó, bạn có thể giết hoặc vô hiệu hóa một lần tại một thời điểm, cho đến khi thủ phạm của bạn được phát hiện. Tôi hầu như không bao giờ có hơn 4-5 quy trình sử dụng nó. Nếu bạn không chạy lời nhắc lệnh với tư cách quản trị viên, nó có thể cho 0 kết quả.

Dưới đây là tất cả các ứng dụng tôi đã phát hiện ra rằng can thiệp vào net.pipe:

  • "HP Support Solutions Khung Service" - chỉ có một số phiên bản bị ảnh hưởng
  • "Garmin Dịch vụ cốt lõi Update" - được sửa trong các phiên bản mới hơn nhưng đã hết hộp
  • "Dịch vụ WBE" - được sử dụng bởi một máy tính xách tay đôi dell kết hợp với ion
  • "Intel (R) An ninh Assist" Dịch vụ - tôi thấy trên một vài Win10 máy tính xách tay đầu năm 2016.
  • "Baraccuda WSA Service" - Web Security Agent. Có lẽ sẽ làm phiền một khách hàng nếu bạn vô hiệu hóa điều này.
  • "DropboxOEM.exe" - Một biến thể của Dropbox để đưa vào máy tính của cửa hàng mua. Chỉ nhận thấy trên Win10 cho đến nay.Điều này là duy nhất, bởi vì nó là lần đầu tiên tôi đã tìm thấy đó không phải là một dịch vụ cửa sổ, tốt nhất tôi có thể nói.
  • "Dịch vụ MTC" - Được cài đặt trên một số PC của Getac. Không chắc chắn những gì nó làm.
  • "pcdrcui.exe" - Không phải là dịch vụ nhưng chạy với tư cách quản trị viên. Thành phần của SupportAssist của Dell.

Tôi hỗ trợ ứng dụng yêu cầu net.pipe, vì vậy tôi sẽ cập nhật danh sách này khi tôi tìm thấy nhiều dịch vụ hơn.

+0

Cảm ơn rất nhiều vì câu trả lời rất hữu ích này, đã cứu chúng tôi rất nhiều đau đầu! Chúng tôi đã có tình huống tương tự như OP và có thể xác định thủ phạm bằng cách làm theo hướng dẫn của bạn; trong trường hợp của chúng tôi, nó là ** "Wonderware InTouch IData Service" ** ('SE.Scada.Asb.InTouchDataService.exe') đi kèm với hệ thống Wonderware InTouch HMI (Tôi không biết chính xác nó làm gì). Giết chết quá trình này đột nhiên làm cho ứng dụng dựa trên WCF của chúng ta hoạt động trở lại. – Golvellius