Can't get salt-api to work - Help!!

4,769 views
Skip to first unread message

JanetB

unread,
Jun 12, 2013, 7:53:57 PM6/12/13
to salt-...@googlegroups.com
Hi,
I'm trying to use the salt-api. I have salt 0.15.1 and salt-api 0.8.1. In my master config file I have:
external_auth:
  pam:
    jmb:
      - .*
    root:
      - .*

rest_cherrypy:
  port: 8000
  debug: True

I start the salt-master and the salt-api and try to connect with curl:
>
curl -i http://localhost:8000
HTTP/1.1 401 Unauthorized
Content-Length: 57
Vary: Accept-Encoding
Server: CherryPy/3.2.2
Allow: GET, HEAD, POST
Date: Wed, 12 Jun 2013 23:35:45 GMT
Content-Type: application/json
Www-Authenticate: Session
Set-Cookie: session_id=d327d6d347e6d9005ade52fab8977a51268babb1; expires=Thu, 13 Jun 2013 09:35:45 GMT; Path=/

{"status": "401 Unauthorized", "return": "Please log in"}

I get the same error trying to use my web browser.

If I enable ssl in my master config file:
external_auth:
  pam:
    jmb:
      - .*
    root:
      - .*

rest_cherrypy:
  port: 8000
  ssl_crt: /etc/pki/tls/certs/localhost.crt
  ssl_key: /etc/pki/tls/certs/localhost.key

And then try connecting I get:
curl -i https://localhost:8000
curl: (60) Peer certificate cannot be authenticated with known CA certificates
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.


So, I do:
> salt '*' tls.create_self_signed_cert

I still can't use curl to connect:
> curl -i https://localhost:8000
curl: (60) Peer certificate cannot be authenticated with known CA certificates
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.


So, I try this:
> curl -u root -i https://localhost:8000
Enter host password for user 'root':
curl: (6) Couldn't resolve host 'jmb'
curl: (60) Peer certificate cannot be authenticated with known CA certificates
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.


No matter what I enter for the password it fails.

Can someone help me figure out what I'm doing wrong?

Thanks!

Seth House

unread,
Jun 12, 2013, 8:29:07 PM6/12/13
to salt-...@googlegroups.com
On Wed, Jun 12, 2013 at 5:53 PM, JanetB <jbors...@gmail.com> wrote:
> In my
> master config file I have:

Your config looks correct other than the root user cannot be used with
external_auth. IIRC, there was a Salt ticket about this and it turned
out to be a (purposeful?) PAM limitation.

> I start the salt-master and the salt-api and try to connect with curl:
> {"status": "401 Unauthorized", "return": "Please log in"}

Do those user credentials work using Salt's regular CLI? Verify via:

salt -a pam '*' test.ping

> So, I try this:
>> curl -u root -i https://localhost:8000

salt-api does not use HTTP-auth but rather cookie-based auth so you
must first authenticate via the /login URL then use the returned token
in subsequent requests. The token is returned both in the response and
as a cookie. I often use curl's mechanism to store cookies to a text
file so I don't have to copy/paste the token each time. Something like
this:

curl -c /tmp/cookies.txt -sS localhost:8000/login -H "Accept:
application/x-yaml" -d username='saltdev' -d password='saltdev' -d
eauth='pam'

curl -b /tmp/cookies.txt -sS localhost:8000 -H 'Accept:
application/x-yaml' -d client='local' -d tgt='*' -d fun='test.ping'

curl -b /tmp/cookies.txt -sS localhost:8000 -H 'Accept:
application/x-yaml' -d client='local' -d tgt='*' -d fun='disk.usage'

JanetB

unread,
Jun 12, 2013, 8:58:02 PM6/12/13
to salt-...@googlegroups.com, se...@eseth.com
I verified the user credentials for the user jmb and it worked fine.
Next, I tried using curl as you show and it worked! WooHoo!!
Good to know about the root user, I'll remove that entry.

Thanks for you help, Seth! I was going crazy trying to figure out what I had wrong. I'm pretty new to all this. :)

Seth House

unread,
Jun 13, 2013, 1:09:07 AM6/13/13
to salt-...@googlegroups.com
On Wed, Jun 12, 2013 at 6:58 PM, JanetB <jbors...@gmail.com> wrote:
> I verified the user credentials for the user jmb and it worked fine.
> Next, I tried using curl as you show and it worked! WooHoo!!

I'm glad you got it working. The authentication step wasn't documented
very well so I added a paragraph about that just now. Thanks for the
report! :-)

jb_horses

unread,
Jun 13, 2013, 2:33:14 PM6/13/13
to salt-...@googlegroups.com, se...@eseth.com
It looks like I haven't got things quite right yet. When my master config file doesn't have the debug: True line in it I can't connect at all. Here's my master config file section:


external_auth:
  pam:
    jmb:
      - .*

rest_cherrypy:
  port: 8000
  ssl_crt: /etc/pki/tls/certs/localhost.crt
  ssl_key: /etc/pki/tls/certs/localhost.key

Then, I verify I can connect with salt:

> salt -a pam '*' test.ping
username: jmb
password:
minion1:
    True
[1]+  Done                    emacs /etc/salt/minion

So, that works fine. Next, I try to connect with my host:


> curl -c /tmp/cookies.txt -sS localhost:8000 -H "Accept:application/x-yaml" -d username='jmb' -d password='jmb' -d eauth='pam'
The client sent a plain HTTP request, but this server only speaks HTTPS on this port.

> curl -c /tmp/cookies.txt -sS https://localhost:8000 -H "Accept:application/x-yaml" -d username='jmb' -d password='jmb' -d eauth='pam'

curl: (60) Peer certificate cannot be authenticated with known CA certificates
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

If I add back the debug: True line to my master config then I can connect:
> curl -c /tmp/cookies.txt -sS localhost:8000/login -H "Accept:application/x-yaml" -d username='jmb' -d password='jmb' -d eauth='pam'
return:
- eauth: pam
  expire: 1371191390.0130229
  perms:
  - .*
  start: 1371148190.0130219
  token: 049520e69daa4cd3b7b70245622f3de311183698
  user: jmb

And I can execute modules:

> curl -b /tmp/cookies.txt -sS localhost:8000 -H "Accept:application/x-yaml" -d client='local' -d tgt='*' -d fun='test.ping'
return:
- minion1: true

Any ideas? Thanks!

JanetB

unread,
Jun 13, 2013, 2:36:58 PM6/13/13
to salt-...@googlegroups.com
In my previous post please ignore the line:

[1]+  Done                    emacs /etc/salt/minion

It was a copy/paste error!

-- Janet

Seth House

unread,
Jun 13, 2013, 2:42:43 PM6/13/13
to salt-...@googlegroups.com
On Thu, Jun 13, 2013 at 12:33 PM, jb_horses
<janet.b...@codefutures.com> wrote:
>> curl -c /tmp/cookies.txt -sS https://localhost:8000 -H
>> "Accept:application/x-yaml" -d username='jmb' -d password='jmb' -d
>> eauth='pam'
> curl: (60) Peer certificate cannot be authenticated with known CA
> certificates

This may be specific to curl. Try passing the ``-k`` option to ignore
certificate validation. (Or try in a browser.)

When you add ``debug: True`` to the settings it uses the non-SSL
development server. When debug is off it uses a different
production-ready server and forces SSL.

Janet Borschowa

unread,
Jun 13, 2013, 4:54:28 PM6/13/13
to salt-...@googlegroups.com
Adding -k seemed to work. Here's my output:
> curl -k -c /tmp/cookies.txt -sS localhost:8000/login -H "Accept:application/x-yaml" -d username='jmb' -d password='jmb' -d eauth='pam'
return:
- eauth: pam
  expire: 1371199329.4316969
  perms:
  - .*
  start: 1371156129.4316959
  token: aabe7e8da6982997ce038a8a60796eb670b9d172
  user: jmb

And, I can follow that with this and it also appears to work:

> curl -b /tmp/cookies.txt -sS localhost:8000 -H "Accept:application/x-yaml" -d client='local' -d tgt='*' -d fun='test.ping'
return:
- minion1: true

So, it looks like I'm up and running. One remaining question, when I have the line "debug: True" in my master configuration file, I can't use a command like this:
It gives me the 401 error, but this works:
> curl -i http://localhost:8000/run
And, in my browser, I can also use, http://localhost:8000/run and it shows the output:
{"output": ["application/json", "application/x-yaml"], "clients": ["local", "local_async", "runner", "wheel"], "return": "Welcome"}

but http://localhost:8000 still doesn't work.

Is that expected?

Once again, thank you for your help, it is greatly appreciated!
-- Janet




--
You received this message because you are subscribed to a topic in the Google Groups "Salt-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/salt-users/H-MyrvJbyGE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to salt-users+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



Seth House

unread,
Jun 13, 2013, 7:34:46 PM6/13/13
to salt-...@googlegroups.com
On Thu, Jun 13, 2013 at 2:54 PM, Janet Borschowa <jbors...@gmail.com> wrote:
> Is that expected?

That is expected, though perhaps inconsistent. The /run URL defers
authentication until it runs a command while the rest of the app does
early session verification. If you first authenticate you should see
the same welcome message at the root URL.

The exact functionality of GET requests to the root URL is still
somewhat undecided. If it makes sense to make it into some kind of
status display that requires performing an execution then the /run URL
will return a 401 as-is; if it makes sense to keep it as a static
welcome message then we should allow unauthenticated access to the
root URL.
Message has been deleted
Message has been deleted

JanetB

unread,
Jun 18, 2013, 10:31:15 PM6/18/13
to salt-...@googlegroups.com
Hi,
I'm now trying the same thing on mac osx. I have salt 0.15.3 and salt-api 0.8.1. I can successfully use:
> salt -a pam '*' test.ping

But, when I try to connect to the server I am getting the error:
> curl -k -v -c ./cookies.txt  -sS localhost:8000/login -H "Accept:application/x-yaml"  -d eauth:'pam' -d username:'jmb' -d password:'mypassword'
* About to connect() to localhost port 8000 (#0)
*   Trying ::1...
* Connection refused
*   Trying 127.0.0.1...
* connected
* Connected to localhost (127.0.0.1) port 8000 (#0)
> POST /login HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5
> Host: localhost:8000
> Accept:application/x-yaml
> Content-Length: 40
> Content-Type: application/x-www-form-urlencoded
* upload completely sent off: 40 out of 40 bytes
127.0.0.1 - - [18/Jun/2013:19:16:01] "POST /login HTTP/1.1" 401 1671 "" "curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5"
< HTTP/1.1 401 Unauthorized
< Content-Length: 1671
< Vary: Accept-Encoding
< Server: CherryPy/3.2.2
< Allow: GET, HEAD, POST
< Date: Wed, 19 Jun 2013 02:16:00 GMT
< Content-Type: text/html;charset=utf-8
* Added cookie session_id="f4ca71a80a101e5b1f249010bf7101aa177c793a" for domain localhost, path /, expire 1371644160
< Set-Cookie: session_id=f4ca71a80a101e5b1f249010bf7101aa177c793a; expires=Wed, 19 Jun 2013 12:16:00 GMT; Path=/
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
    <title>401 Unauthorized</title>
    <style type="text/css">
    #powered_by {
        margin-top: 20px;
        border-top: 2px solid black;
        font-style: italic;
    }

    #traceback {
        color: red;
    }
    </style>
</head>
    <body>
        <h2>401 Unauthorized</h2>
        <p>Could not authenticate using provided credentials</p>
        <pre id="traceback">Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/CherryPy-3.2.2-py2.7.egg/cherrypy/_cprequest.py", line 656, in respond
    response.body = self.handler()
  File "/Library/Python/2.7/site-packages/CherryPy-3.2.2-py2.7.egg/cherrypy/lib/encoding.py", line 188, in __call__
    self.body = self.oldhandler(*args, **kwargs)
  File "/Library/Python/2.7/site-packages/saltapi/netapi/rest_cherrypy/app.py", line 230, in hypermedia_handler
    ret = cherrypy.serving.request._hypermedia_inner_handler(*args, **kwargs)
  File "/Library/Python/2.7/site-packages/CherryPy-3.2.2-py2.7.egg/cherrypy/_cpdispatch.py", line 34, in __call__
    return self.callable(*self.args, **self.kwargs)
  File "/Library/Python/2.7/site-packages/saltapi/netapi/rest_cherrypy/app.py", line 820, in POST
    'Could not authenticate using provided credentials')
HTTPError: (401, 'Could not authenticate using provided credentials')
</pre>
    <div id="powered_by">
    <span>Powered by <a href="http://www.cherrypy.org">CherryPy 3.2.2</a></span>
    </div>
    </body>
</html>
* Connection #0 to host localhost left intact
* Closing connection #0

When I try via my browser I get the expected error message:
{"status": "401 Unauthorized", "return": "Please log in"}

Any ideas of what I could try next?

Thanks,
-- Janet


Seth House

unread,
Jun 19, 2013, 1:03:30 PM6/19/13
to salt-...@googlegroups.com
On Tue, Jun 18, 2013 at 8:28 PM, JanetB <jbors...@gmail.com> wrote:
> Any ideas of what I could try next?

Using PAM authentication on OS X has not be tested to my knowledge.
There is an open bug with PAM on OpenBSD [1]; it is quite possible
that bug also affects OS X.

If you have a few minutes it would be helpful if you could try to
ferret out that same traceback (or another) on OS X. The best way is
to stop the Salt master and then start it in the foreground with
tuned-up logging (``salt-master -l debug``). Then try to authenticate
again to see if anything helpful is output.

[1] https://github.com/saltstack/salt/issues/4127

jb_horses

unread,
Jun 20, 2013, 11:37:06 AM6/20/13
to salt-...@googlegroups.com, se...@eseth.com
I'll get more info on the problem and let you know what I find. It appears that the problem is specific to curl on os x because I can successfully connect and authenticate from my linux machine and also from a java application on my os x machine. 

-- Janet

JanetB

unread,
Jun 21, 2013, 2:27:52 PM6/21/13
to salt-...@googlegroups.com, se...@eseth.com
Hi Seth,
Here's more information on the problem connecting to the salt-api on mac os x using curl.

Here's the command line I execute:

curl -k -v -c ./cookies.txt  -sS localhost:8000/login  -H "Accept:application/x-yaml"  -d username:'janetuser' -d password:'jmb' -d eauth='pam'


And here's the output from salt-api (started with the command: salt-api -l debug):


[INFO    ] 127.0.0.1 - - [21/Jun/2013:11:20:10] "POST /login HTTP/1.1" 401 1671 "" "curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5"



[CRITICAL] Authentication module threw an exception: auth() takes exactly 2 arguments (0 given)

127.0.0.1 - - [21/Jun/2013:11:20:38] "POST /login HTTP/1.1" 401 1671 "" "curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5"

[INFO    ] 127.0.0.1 - - [21/Jun/2013:11:20:38] "POST /login HTTP/1.1" 401 1671 "" "curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5"


The same username and password are used in my java application and that successfully connects.

Getting curl to work would be convenient but I am OK without it because I can connect via my java application which is what I need to do right now.

Thanks,
-- Janet

Seth House

unread,
Jun 21, 2013, 4:23:57 PM6/21/13
to salt-...@googlegroups.com
Doh! There is an error in that curl command. Sorry I missed that the
first time (seeing the error message made me take a second look). I
think it should work if you replace the colon with an equal sign in
the username & password params.

On Fri, Jun 21, 2013 at 12:27 PM, JanetB <jbors...@gmail.com> wrote:
> curl -k -v -c ./cookies.txt -sS localhost:8000/login -H
> "Accept:application/x-yaml" -d username:'janetuser' -d password:'jmb' -d
> eauth='pam'
>

JanetB

unread,
Jun 21, 2013, 6:39:16 PM6/21/13
to salt-...@googlegroups.com, se...@eseth.com
Ahhhggg!! I must be going blind! I should have seen that too :-) Thank you!!
Reply all
Reply to author
Forward
0 new messages