VPN ਜੁੜਦਾ ਹੈ, ਅਤੇ ਤਿੰਨ ਅਸੰਬੰਧਿਤ ਸਾਧਨ ਤਿੰਨ ਵੱਖਰੇ ਤਰੀਕਿਆਂ ਨਾਲ ਫੇਲ੍ਹ ਹੁੰਦੇ ਹਨ ਉਸੇ ਦੁਪਹਿਰ। mitmproxy ਬੇਨਤੀਆਂ ਵੇਖਣਾ ਬੰਦ ਕਰ ਦਿੰਦਾ ਹੈ, Chrome ਡੀਬੱਗਰ ਨੂੰ ਮਨਾਹੀ ਕਰਦਾ ਹੈ, ਅਤੇ Gradle BindException ਸਥਾਨਕ ਸਾਕਟ ਬਾਈਂਡ ਕਰਦਿਆਂ ਸੁੱਟਦਾ ਹੈ। ਸਾਂਝਾ ਸ਼ੱਕ ਇਹ ਹੈ ਕਿ ਸੁਰੰਗ localhost ਨੂੰ ਰੋਕਦੀ ਹੈ। ਇਹ ਨਹੀਂ ਕਰ ਸਕਦੀ: 127.0.0.1 ਕਰਨਲ ਦੇ ਅੰਦਰ ਸੰਭਾਲਿਆ ਜਾਂਦਾ ਹੈ ਅਤੇ ਕਦੇ ਅਡੈਪਟਰ ਤੱਕ ਨਹੀਂ ਪਹੁੰਚਦਾ, ਗੇਟਵੇ ਦੀ ਗੱਲ ਤਾਂ ਛੱਡੋ।

ਤਿੰਨ ਪਰਤਾਂ, ਤਿੰਨ ਵੱਖਰੇ ਭੰਗ

ਕਲਾਇੰਟ ਨਾਲ ਜੋ ਬਦਲਿਆ ਉਹ loopback ਵੱਲ ਜਾਣ ਵਾਲਾ ਰਸਤਾ ਨਹੀਂ। ਉਹ ਸਥਾਨਕ ਪ੍ਰੌਕਸੀ, ਮਸ਼ੀਨ ਦਾ ਭਰੋਸਾ ਸਟੋਰ ਅਤੇ ਪੈਕੇਟ ਫਿਲਟਰ ਹਨ, ਅਤੇ ਹਰ ਇੱਕ ਡਿਵੈਲਪਰ ਦੇ ਕੰਮ ਦੇ ਪ੍ਰਵਾਹ ਦਾ ਵੱਖਰਾ ਹਿੱਸਾ ਤੋੜਦਾ ਹੈ। ਲੱਛਣ ਨੂੰ ਸਹੀ ਕਤਾਰ ਵਿੱਚ ਰੱਖਣਾ ਹੀ ਨਿਦਾਨ ਦਾ ਵੱਡਾ ਹਿੱਸਾ ਹੈ:

SymptomLayerFirst check
Proxy sees no trafficLocal proxy or listenerss -lntp, or netstat -ano on Windows
TLS error in one tool onlyTrust storeWhich CA bundle does that runtime read?
Local bind or connect refusedPacket filter or port ownerWho holds the port, and what rule drops it?

ਇਸ ਕਿਸਮ ਦੀ ਲਗਭਗ ਹਰ ਰਿਪੋਰਟ ਆਖਰੀ ਕਤਾਰ ਤੋਂ ਸ਼ੁਰੂ ਹੋ ਕੇ ਉੱਪਰ ਜਾਂਦੀ ਹੈ, ਜੋ ਉਲਟਾ ਹੈ। ਸੁਰੰਗ ਉਹ ਇੱਕੋ ਪਰਤ ਹੈ ਜੋ ਸਾਬਤ ਤੌਰ 'ਤੇ loopback ਟ੍ਰੈਫਿਕ ਨਹੀਂ ਵੇਖ ਸਕਦੀ, ਇਸ ਲਈ ਉਸ ਨੂੰ ਸਭ ਤੋਂ ਘੱਟ ਸ਼ੱਕ ਮਿਲਣਾ ਚਾਹੀਦਾ ਹੈ। ਪ੍ਰਕਿਰਿਆ ਨੇ ਕੀ ਬਾਈਂਡ ਕੀਤਾ ਉਸ ਤੋਂ ਸ਼ੁਰੂ ਕਰੋ, ਫਿਰ ਪੁੱਛੋ ਕਿ ਉਹ ਕਿਹੜੇ ਸਰਟੀਫਿਕੇਟਾਂ 'ਤੇ ਭਰੋਸਾ ਕਰਦੀ ਹੈ, ਅਤੇ ਉਸ ਤੋਂ ਬਾਅਦ ਹੀ ਮਸ਼ੀਨ 'ਤੇ ਨੀਤੀ ਵੇਖੋ।

ਸੁਰੰਗ ਤੋਂ ਨਹੀਂ, ਸਰੋਤੇ ਤੋਂ ਸ਼ੁਰੂ ਕਰੋ

ਜਦੋਂ 127.0.0.1:8080 'ਤੇ ਪ੍ਰੌਕਸੀ ਟ੍ਰੈਫਿਕ ਲੈਣਾ ਬੰਦ ਕਰ ਦਿੰਦੀ ਹੈ, ਤਿੰਨ ਵਿੱਚੋਂ ਇੱਕ ਹੋਇਆ: ਉਹ ਕਦੇ ਸ਼ੁਰੂ ਨਹੀਂ ਹੋਈ, ਉਸ ਨੇ ਦੂਜਾ ਪੋਰਟ ਬਾਈਂਡ ਕੀਤਾ, ਜਾਂ ਫਿਲਟਰ ਨੇ loopback ਕਨੈਕਸ਼ਨ ਸੁੱਟ ਦਿੱਤਾ। ਸੁਣਦੇ ਸਾਕਟਾਂ ਦੀ ਸੂਚੀ ਇੱਕ ਹੀ ਕਮਾਂਡ ਵਿੱਚ ਜਵਾਬ ਦਿੰਦੀ ਹੈ, ਅਤੇ ਇਹ ਵੀ ਦਿਖਾਉਂਦੀ ਹੈ ਕਿ ਕਿਹੜੀ ਪ੍ਰਕਿਰਿਆ ਪੋਰਟ ਦੀ ਮਾਲਕ ਹੈ ਜਦੋਂ ਦੋ ਸਾਧਨ ਇਸ 'ਤੇ ਅਸਹਿਮਤ ਹੋਣ ਕਿ ਪਹਿਲਾ ਕੌਣ ਸੀ।

ਰੂਟ ਖੋਜ ਵਿੱਚ ਸਥਾਨਕ ਪਤਾ ਦੂਜੇ ਪਾਸਿਓਂ ਇਹੀ ਗੱਲ ਪੁਸ਼ਟੀ ਕਰਦਾ ਹੈ। ip route get loopback ਮੰਜ਼ਿਲ ਵੱਲ ਇਹ loopback ਯੰਤਰ ਦੀ ਰਿਪੋਰਟ ਕਰਦਾ ਹੈ, ਸੁਰੰਗ ਦੀ ਕਦੇ ਨਹੀਂ, ਅਤੇ ਜਦੋਂ ਕੋਈ ਹੱਲ ਵਜੋਂ ਰੂਟਿੰਗ ਬਦਲਾਅ ਸੁਝਾਉਂਦਾ ਹੈ ਤਾਂ ਇਹ ਤਿਆਰ ਰੱਖਣ ਵਾਲਾ ਲਾਭਦਾਇਕ ਵਾਕ ਹੈ।

ਪ੍ਰੌਕਸੀ ਪਰਤ: ਵਾਤਾਵਰਨ ਕਨਫਿਗਰੇਸ਼ਨ ਨਹੀਂ ਹੈ

ਕਈ ਕਾਰਪੋਰੇਟ ਕਲਾਇੰਟ HTTP ਪ੍ਰੌਕਸੀ ਚਲਾਉਂਦੇ ਹਨ ਅਤੇ ਉਮੀਦ ਕਰਦੇ ਹਨ ਕਿ ਐਪਲੀਕੇਸ਼ਨ ਇਸ ਦੀ ਵਰਤੋਂ ਕਰਨਗੇ। ਸੈੱਟ ਕਰਨਾ HTTPS_PROXY ਸ਼ੈਲ ਵਿੱਚ ਉਸ ਨੂੰ ਮਾਣਨ ਵਾਲੇ ਕਮਾਂਡ-ਲਾਈਨ ਸਾਧਨ ਠੀਕ ਕਰਦਾ ਹੈ, ਅਤੇ ਆਪਣੀ ਸੈਟਿੰਗ ਫਾਈਲ ਪੜ੍ਹਨ ਵਾਲੇ ਸਾਧਨ ਲਈ ਕੁਝ ਨਹੀਂ ਕਰਦਾ। Gradle, Selenium ਅਤੇ gRPC ਹਰ ਇੱਕ ਆਪਣੀ ਕਨਫਿਗਰੇਸ਼ਨ ਨਾਲ ਸਲਾਹ ਕਰਦਾ ਹੈ, ਅਤੇ ਇੱਕ ਟਰਮੀਨਲ ਵਿੱਚ ਐਕਸਪੋਰਟ ਕੀਤੀ ਪ੍ਰੌਕਸੀ IDE ਵੱਲੋਂ ਸ਼ੁਰੂ ਕੀਤੇ ਡੈਮਨ ਲਈ ਅਦ੍ਰਿਸ਼ ਹੁੰਦੀ ਹੈ।

ਕੰਟੇਨਰ ਸਾਧਨ ਆਮ ਤੌਰ 'ਤੇ ਉਹ ਥਾਂ ਹਨ ਜਿੱਥੇ ਇਹ ਦਿਖਾਈ ਦਿੰਦਾ ਹੈ। ਕੰਟੇਨਰ ਦਾ loopback ਉਸ ਦਾ ਆਪਣਾ ਹੁੰਦਾ ਹੈ, ਇਸ ਲਈ 127.0.0.1 ਕੰਟੇਨਰ ਦੇ ਅੰਦਰ ਕਦੇ ਹੋਸਟ ਦੀ ਪ੍ਰੌਕਸੀ ਦਾ ਅਰਥ ਨਹੀਂ ਹੁੰਦਾ; ਹੋਸਟ ਦਾ ਪਤਾ ਜਾਂ ਹੋਸਟ-ਨੈੱਟਵਰਕ ਸੈਟਿੰਗ ਲੋੜੀਂਦੀ ਹੈ। ਜੋ ਹੱਲ ਸ਼ੈਲ ਵਿੱਚ ਕੰਮ ਕਰਦਾ ਹੈ ਅਤੇ ਬਿਲਡ ਵਿੱਚ ਫੇਲ੍ਹ ਹੁੰਦਾ ਹੈ, ਆਮ ਤੌਰ 'ਤੇ ਇਹੀ ਕਤਾਰ ਹੈ, ਸੁਰੰਗ ਨਹੀਂ।

ਭਰੋਸਾ ਪਰਤ: ਸਾਧਨ ਦੂਜਾ ਸਟੋਰ ਪੜ੍ਹਦਾ ਹੈ

ਇੰਟਰਸੈਪਸ਼ਨ ਦੂਜਾ ਬਦਲਾਅ ਹੈ, ਅਤੇ ਇਹ ਸਭ ਤੋਂ ਭੁਲਾਉਣ ਵਾਲੀਆਂ ਗਲਤੀਆਂ ਪੈਦਾ ਕਰਦਾ ਹੈ। ਕਲਾਇੰਟ ਜਾਂਚੇ ਜਾਣ ਵਾਲੇ ਕਨੈਕਸ਼ਨਾਂ ਲਈ ਆਪਣਾ ਸਰਟੀਫਿਕੇਟ ਪੇਸ਼ ਕਰਦਾ ਹੈ, ਇਸ ਲਈ ਕਾਰਪੋਰੇਟ ਰੂਟ 'ਤੇ ਭਰੋਸਾ ਕਰਨ ਵਾਲਾ ਬ੍ਰਾਊਜ਼ਰ ਸਫਲ ਹੁੰਦਾ ਹੈ ਜਦੋਂ ਕਿ ਬੰਡਲ ਕੀਤਾ CA ਸਟੋਰ ਵਾਲਾ ਸਾਧਨ ਫੇਲ੍ਹ ਹੁੰਦਾ ਹੈ। certifi ਰਾਹੀਂ Python requests ਪੁਰਾਣਾ ਉਦਾਹਰਨ ਹੈ: ਆਪਰੇਟਿੰਗ ਸਿਸਟਮ ਦਾ ਸਟੋਰ ਸਹੀ ਹੋ ਸਕਦਾ ਹੈ ਅਤੇ ਬੇਨਤੀ ਫਿਰ ਵੀ ਫੇਲ੍ਹ ਹੁੰਦੀ ਹੈ, ਕਿਉਂਕਿ ਉਹ ਰਨਟਾਈਮ ਇਸ ਨੂੰ ਕਦੇ ਨਹੀਂ ਪੜ੍ਹਦਾ। ਗਲਤੀ ਦੇ ਪਾਠ ਵਿੱਚ ਇੰਟਰਸੈਪਸ਼ਨ ਦਾ ਜ਼ਿਕਰ ਘੱਟ ਹੀ ਹੁੰਦਾ ਹੈ, ਇਸ ਲਈ ਇਸ ਕਤਾਰ ਦਾ ਨਿਦਾਨ ਗਲਤੀ ਨਾਲ ਟੁੱਟੇ ਐਂਡਪੌਇੰਟ ਵਜੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।

ਐਂਡਪੌਇੰਟ ਅਸਲ ਵਿੱਚ ਕੀ ਪੇਸ਼ ਕਰਦਾ ਹੈ ਅਤੇ ਸਾਧਨ ਨੇ ਕੀ ਪ੍ਰਮਾਣਿਤ ਕੀਤਾ, ਇਸ ਦੀ ਤੁਲਨਾ ਕਰੋ। openssl s_client ਸਰਵਰ ਵੱਲੋਂ ਭੇਜੀ ਚੇਨ ਦਿਖਾਉਂਦਾ ਹੈ; ਸਾਧਨ ਦਾ ਆਪਣਾ ਪ੍ਰਮਾਣਿਕਰਨ ਆਉਟਪੁੱਟ ਦਿਖਾਉਂਦਾ ਹੈ ਕਿ ਇਸ ਨੇ ਕੀ ਫੈਸਲਾ ਕੀਤਾ। ਜਦੋਂ ਉਹ ਨਹੀਂ ਮਿਲਦੇ, REQUESTS_CA_BUNDLE ਜਾਂ SSL_CERT_FILE ਉਸ ਰਨਟਾਈਮ ਲਈ ਲੀਵਰ ਹੈ, ਅਤੇ ਕਾਰਪੋਰੇਟ ਰੂਟ ਉਸ ਸਟੋਰ ਵਿੱਚ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ ਜਿਸ ਨੂੰ ਉਹ ਰਨਟਾਈਮ ਪੜ੍ਹਦਾ ਹੈ, ਨਾ ਕਿ ਅਜਿਹੀ ਆਲਮੀ ਥਾਂ ਵਿੱਚ ਜਿਸ ਨੂੰ ਸਿਰਫ਼ ਕੁਝ ਸਾਧਨ ਮਾਣਦੇ ਹਨ।

SSL ਗਲਤੀ ਠੀਕ ਕਰਨ ਵਾਲਾ ਵਰਜ਼ਨ ਬਦਲਾਅ VPN ਦਾ ਨਹੀਂ, ਭਰੋਸਾ ਅਤੇ ਸਾਈਫਰ ਨੀਤੀ ਦਾ ਸਬੂਤ ਹੈ। SOAP ਕਲਾਇੰਟ ਚਲਾਉਣ ਵਾਲੇ Python ਦੇ ਡਾਊਨਗ੍ਰੇਡ ਨੇ ਬੰਡਲ ਕੀਤਾ CA ਸਟੋਰ ਅਤੇ ਡਿਫਾਲਟ TLS ਸੈਟਿੰਗਾਂ ਬਦਲੀਆਂ; ਨੈੱਟਵਰਕ ਰਸਤਾ ਨਹੀਂ ਹਿਲਿਆ।

ਫਿਲਟਰ ਪਰਤ: ਇਹ loopback ਵੀ ਸੁੱਟ ਸਕਦੀ ਹੈ

ਤੀਜਾ ਬਦਲਾਅ ਪੈਕੇਟ ਫਿਲਟਰ ਹੈ, ਅਤੇ ਕੁਝ ਉਤਪਾਦ ਅਜਿਹੇ ਨਿਯਮ ਸਥਾਪਿਤ ਕਰਦੇ ਹਨ ਜੋ ਸੁਰੰਗ ਵਿੱਚ ਨਾ ਆਉਣ ਵਾਲਾ ਟ੍ਰੈਫਿਕ ਸੁੱਟਦੇ ਹਨ। ਸਥਾਨਕ ਸਰੋਤੇ ਵੀ ਸ਼ਾਮਲ ਹੋ ਸਕਦੇ ਹਨ। ਇਹ ਕੰਮ ਕਰਦੇ ਸਾਕਟ ਨੂੰ ਰੱਦ ਕੀਤੇ ਜਾਂ ਸਮਾਂ-ਸਮਾਪਤ ਕਨੈਕਸ਼ਨ ਵਿੱਚ ਬਦਲ ਦਿੰਦਾ ਹੈ, ਅਤੇ ਨਤੀਜਾ ਗਲਤੀ ਮਸ਼ੀਨ 'ਤੇ ਨੀਤੀ ਨਹੀਂ, ਐਪਲੀਕੇਸ਼ਨ ਵਿੱਚ ਬੱਗ ਵਰਗੀ ਦਿਸਦੀ ਹੈ।

ਪੋਰਟ ਦੀ ਮਾਲਕੀ ਇਸ ਪਰਤ ਦਾ ਦੂਜਾ ਅੱਧਾ ਹਿੱਸਾ ਹੈ। BindException ਦਾ ਅਰਥ ਹੈ ਕਿ ਸਾਕਟ ਖੋਲ੍ਹਿਆ ਨਹੀਂ ਜਾ ਸਕਿਆ, ਜੋ ਕਨੈਕਸ਼ਨ ਰੱਦ ਹੋਣ ਤੋਂ ਵੱਖਰੀ ਅਸਫਲਤਾ ਹੈ। ਫਿਲਟਰ ਨੂੰ ਦੋਸ਼ ਦੇਣ ਤੋਂ ਪਹਿਲਾਂ ਜਾਂਚੋ ਕਿ ਕੋਈ ਹੋਰ ਪ੍ਰਕਿਰਿਆ ਪੋਰਟ ਪਹਿਲਾਂ ਹੀ ਰੱਖਦੀ ਹੈ ਜਾਂ ਨਹੀਂ, ਫਿਰ ਅਜਿਹਾ ਨਿਯਮ ਲੱਭੋ ਜੋ ਸਥਾਨਕ ਟ੍ਰੈਫਿਕ ਸੁੱਟਦਾ ਹੈ ਅਤੇ ਉਤਪਾਦ ਜੋ ਸਭ ਤੋਂ ਤੰਗ ਆਗਿਆ ਦਾ ਸਮਰਥਨ ਕਰਦਾ ਹੈ ਉਹ ਜੋੜੋ। ਇੱਕੋ ਡੀਬੱਗ ਪੋਰਟ ਲਈ ਮੁਕਾਬਲਾ ਕਰਦੇ ਦੋ ਸਾਧਨ ਨੀਤੀ-ਰੋਕ ਵਾਂਗ ਹੀ ਉਹੀ ਸੁਨੇਹਾ ਦਿੰਦੇ ਹਨ, ਅਤੇ ਉਨ੍ਹਾਂ ਵਿੱਚੋਂ ਸਿਰਫ਼ ਇੱਕ ਹੀ ਫਾਇਰਵਾਲ ਬਦਲਾਅ ਨਾਲ ਠੀਕ ਹੁੰਦਾ ਹੈ।

Chrome ਦਾ ਡੀਬੱਗ ਪੋਰਟ ਉਸੇ ਪਰਿਵਾਰ ਵਿੱਚ ਫੇਲ੍ਹ ਹੁੰਦਾ ਹੈ। ਬ੍ਰਾਊਜ਼ਰ ਸ਼ੁਰੂ ਹੁੰਦਾ ਹੈ, ਡਰਾਈਵਰ DevTools ਐਂਡਪੌਇੰਟ ਤੱਕ ਨਹੀਂ ਪਹੁੰਚ ਸਕਦਾ, ਅਤੇ ਸੁਨੇਹਾ ਨੈੱਟਵਰਕ ਦੀ ਬਜਾਏ DevTools ਦਾ ਨਾਮ ਲੈਂਦਾ ਹੈ। ਵਾਧੂ ਲਾਂਚ ਫਲੈਗ ਅਤੇ ਬੇਲੋੜਾ ਡਰਾਈਵਰ ਮੈਨੇਜਰ ਬਦਲਦੇ ਹਨ ਕਿ ਕਿਹੜੀ ਪ੍ਰਕਿਰਿਆ ਪੋਰਟ ਦੀ ਮਾਲਕ ਹੈ, ਇਸ ਲਈ ਉਨ੍ਹਾਂ ਨੂੰ ਹਟਾਉਣਾ ਕਦੇ-ਕਦੇ VPN ਠੀਕ ਹੋਇਆ ਜਾਪਦਾ ਹੈ।

ਜੋ ਪਰਤ ਫੇਲ੍ਹ ਹੋਈ ਉਸ ਦੀ ਮੁਰੰਮਤ ਕਰੋ

ਸੁਰੰਗ ਦੀ ਨਹੀਂ, ਜੋ ਪਰਤ ਫੇਲ੍ਹ ਹੋਈ ਉਸ ਦੀ ਮੁਰੰਮਤ ਕਰੋ। ਪਹੁੰਚ ਤੋਂ ਬਾਹਰਲੇ loopback ਸਰੋਤੇ ਦਾ ਸਰੋਤਾ ਜਾਂ ਪੋਰਟ ਸੁਧਾਰਨਾ ਪੈਂਦਾ ਹੈ। ਭਰੋਸੇਯੋਗ ਨਾ ਹੋਣ ਵਾਲੇ ਸਰਟੀਫਿਕੇਟ ਲਈ ਕਾਰਪੋਰੇਟ ਰੂਟ ਉਸੇ ਥਾਂ ਸਥਾਪਿਤ ਕਰਨਾ ਪੈਂਦਾ ਹੈ ਜਿੱਥੇ ਉਹ ਖਾਸ ਰਨਟਾਈਮ ਵੇਖਦਾ ਹੈ, ਅਪਵਾਦ ਤੰਗ ਰੱਖਦਿਆਂ। ਸਥਾਨਕ ਟ੍ਰੈਫਿਕ ਸੁੱਟਣ ਵਾਲੇ ਫਿਲਟਰ ਲਈ ਬੰਦ ਫਿਲਟਰ ਦੀ ਬਜਾਏ ਖਾਸ ਆਗਿਆ ਨਿਯਮ ਚਾਹੀਦਾ ਹੈ, ਕਿਉਂਕਿ ਬੰਦ ਕਰਨ ਨਾਲ ਜੋ ਕੁਝ ਇਹ ਬਚਾ ਰਿਹਾ ਸੀ ਉਹ ਵੀ ਮੁੜ ਖੁੱਲ੍ਹ ਜਾਂਦਾ ਹੈ।

VPN ਨੂੰ ਮੁੜ ਜੋੜਨਾ ਇਨ੍ਹਾਂ ਵਿੱਚੋਂ ਕਿਸੇ ਵੀ ਪਰਤ ਦੀ ਜਾਂਚ ਨਹੀਂ ਕਰਦਾ। ਇਹ ਸਿਰਫ਼ ਉਹੀ ਬਦਲਾਅ ਮੁੜ ਚਲਾਉਂਦਾ ਹੈ ਜਿਸ ਨੇ ਉਨ੍ਹਾਂ ਨੂੰ ਤੋੜਿਆ ਸੀ, ਇਸ ਲਈ ਉਹੀ ਤਿੰਨ ਅਸਫਲਤਾਵਾਂ ਹਰ ਮੁੜ-ਕਨੈਕਸ਼ਨ ਤੋਂ ਬਾਅਦ ਵਾਪਸ ਆਉਂਦੀਆਂ ਹਨ ਅਤੇ ਕਲਾਇੰਟ ਨੂੰ ਨਿਸ਼ਕ੍ਰਿਆ ਛੱਡਣ ਵਾਲੇ ਹਰ ਰੀਬੂਟ ਤੋਂ ਬਾਅਦ ਗਾਇਬ ਹੋ ਜਾਂਦੀਆਂ ਹਨ।

ਸੰਬੰਧਿਤ ਲੇਖ